سؤال

ما هو std::pair لماذا سأستخدمه، وما هي فوائده boost::compressed_pair يحضر؟

هل كانت مفيدة؟

المحلول

std::pair هو نوع بيانات لتجميع قيمتين معًا ككائن واحد. std::map يستخدمه لأزواج المفاتيح والقيمة.

بينما كنت تتعلم pair, ، يمكنك التحقق من ذلك tuple.انها مثل pair ولكن لتجميع عدد تعسفي من القيم. tuple هو جزء من TR1 والعديد من المترجمين يدرجونه بالفعل مع تطبيقات المكتبة القياسية الخاصة بهم.

راجع أيضًا الفصل الأول "الصفوف" من الكتاب ملحقات مكتبة C++ القياسية:البرنامج التعليمي والمرجع بقلم بيت بيكر، ISBN-13:9780321412997 للتوضيح الشامل.

alt text

نصائح أخرى

compressed_pair يستخدم بعض الخداع القالب لتوفير المساحة.في C++، لا يمكن أن يكون للكائن (صغير o) نفس عنوان كائن مختلف.

لذلك حتى لو كان لديك

struct A { };

Aلن يكون حجم 0، لأنه بعد ذلك:

A a1;
A a2;
&a1 == &a2;

سيعقد، وهو غير مسموح به.

لكن سيفعل العديد من المترجمين ما يسمى "تحسين الفئة الأساسية الفارغة":

struct A { };
struct B { int x; };
struct C : public A { int x; };

هنا، لا بأس به B و C أن يكون لها نفس الحجم، حتى لو sizeof(A) لا يمكن أن يكون صفراً.

لذا boost::compressed_pair يستفيد من هذا التحسين وسيرث، حيثما أمكن، أحد الأنواع الموجودة في الزوج إذا كان فارغًا.

لذلك أ std::pair قد يبدو الأمر كما يلي (لقد حذفت صفقة جيدة، والممثلين، وما إلى ذلك):

template<typename FirstType, typename SecondType>
struct pair {
   FirstType first;
   SecondType second;
};

وهذا يعني إذا كان أي منهما FirstType أو SecondType يكون A, ، لك pair<A, int> يجب أن يكون أكبر من sizeof(int).

ولكن إذا كنت تستخدم compressed_pair, ، سيبدو الكود الذي تم إنشاؤه مشابهًا لما يلي:

 struct compressed_pair<A,int> : private A {
    int second_;
    A first() { return *this; }
    int second() { return second_; }
 };

و compressed_pair<A,int> سيكون بحجم sizeof(int) فقط.

تحتاج أحيانًا إلى إرجاع قيمتين من دالة، وغالبًا ما يكون إنشاء فئة لذلك أمرًا مبالغًا فيه.

std:pair يكون مفيدًا في تلك الحالات.

أعتقد أن Boost:compressed_pair قادر على تحسين أعضاء الحجم 0.وهو مفيد في الغالب لآلات القوالب الثقيلة في المكتبات.

إذا كنت تتحكم في الأنواع مباشرة، فهذا غير ذي صلة.

قد يبدو غريبًا أن نسمع أن Compressed_pair يهتم ببضعة بايتات.ولكن يمكن أن يكون الأمر مهمًا في الواقع عندما يفكر المرء في المكان الذي يمكن فيه استخدام زوج مضغوط.على سبيل المثال دعونا نفكر في هذا الكود:

boost::function<void(int)> f(boost::bind(&f, _1));

يمكن أن يكون فجأة تأثيرًا كبيرًا لاستخدام Compressed_pair في الحالات الموضحة أعلاه.ماذا يمكن أن يحدث إذا قام Boost::bind بتخزين مؤشر الوظيفة والعنصر النائب _1 كأعضاء في حد ذاته أو في std::pair في ذاته؟حسنًا، يمكن أن ينتفخ حتى sizeof(&f) + sizeof(_1).بافتراض أن مؤشر الدالة يحتوي على 8 بايت (ليس من غير المألوف خاصة بالنسبة لوظائف الأعضاء) وأن العنصر النائب يحتوي على بايت واحد (راجع إجابة لوغان لمعرفة السبب)، فقد نحتاج إلى 9 بايت لكائن الربط.بسبب المحاذاة، يمكن أن يزيد هذا إلى 12 بايت على نظام 32 بت المعتاد.

boost::function يشجع تطبيقاته على تطبيق تحسين الكائنات الصغيرة.وهذا يعني أن ل صغير functors، مخزن مؤقت صغير مضمن مباشرة في boost::function يتم استخدام الكائن لتخزين functor.بالنسبة للوظائف الأكبر حجمًا، يجب استخدام الكومة باستخدام عامل التشغيل الجديد للحصول على الذاكرة.تعزيز حولها الإصدار 1.34, ، تقرر اعتماده هذا التحسين, ، لأنه كان من المتوقع أن يحصل المرء على بعض فوائد الأداء الرائعة جدًا.

الآن، الحد المعقول (ولكن ربما لا يزال صغيرًا جدًا) لمثل هذا المخزن المؤقت الصغير سيكون 8 بايت.وهذا يعني أن كائن الربط البسيط الخاص بنا سيكون كذلك لا يتناسب مع المخزن المؤقت الصغير، وسيتطلب تخزين مشغل جديد.إذا كان كائن الربط أعلاه سيستخدم ملف compressed_pair, ، يمكنه بالفعل تقليل حجمه إلى 8 بايت (أو 4 بايت لمؤشر الوظيفة غير العضو غالبًا)، لأن العنصر النائب ليس أكثر من كائن فارغ.

لذا، فإن ما قد يبدو وكأنه مجرد إضاعة الكثير من التفكير لبضعة بايتات فقط يمكن أن يكون له في الواقع تأثير كبير على الأداء.

إنها فئة قياسية لتخزين زوج من القيم.يتم إرجاعها/استخدامها بواسطة بعض الوظائف القياسية، مثل std::map::insert.

boost::compressed_pair يدعي أنه أكثر كفاءة: انظر هنا

std::pair مفيد لاثنين من فئات الحاويات الأخرى في STL.

على سبيل المثال:

std::map<>
std::multimap<> 

يقوم كلاهما بتخزين std::pairs من المفاتيح والقيم.

عند استخدام الخريطة والخريطة المتعددة، يمكنك غالبًا الوصول إلى العناصر باستخدام مؤشر إلى زوج.

معلومات إضافية:يكون Boost::compressed_pair مفيدًا عندما يكون أحد أنواع الزوج عبارة عن بنية فارغة.يُستخدم هذا غالبًا في البرمجة الوصفية للقالب عندما يتم استنتاج أنواع الأزواج برمجيًا من الأنواع الأخرى.في النهاية، عادةً ما يكون لديك شكل من أشكال "البنية الفارغة".

أفضّل std::pair لأي استخدام "عادي"، إلا إذا كنت من محبي برمجة القوالب الثقيلة.

إنه ليس سوى هيكل به متغيرين تحت الغطاء.

أنا في الواقع لا أحب استخدام std::pair لإرجاع الوظائف.يجب على قارئ الكود أن يعرف ما هو .first وما هو . Second.

الحل الوسط الذي أستخدمه أحيانًا هو إنشاء مراجع ثابتة على الفور لـ .first و. Second، مع تسمية المراجع بوضوح.

ما هو std::pair، لماذا أستخدمه؟

إنه مجرد عنصرين بسيطين.تم تعريفه في الإصدار الأول من المحكمة الخاصة بلبنان في الأوقات التي لم يكن فيها المترجمون يدعمون على نطاق واسع القوالب وتقنيات البرمجة الوصفية التي ستكون مطلوبة لتنفيذ نوع أكثر تعقيدًا من الصف مثل Boost.Tuple.

إنه مفيد في العديد من المواقف. std::pair يستخدم في الحاويات الترابطية القياسية.ويمكن استخدامه كشكل بسيط من النطاق std::pair<iterator, iterator> - لذلك يمكن تحديد الخوارزميات التي تقبل كائنًا واحدًا يمثل النطاق بدلاً من تكرارين منفصلين.(إنه بديل مفيد في العديد من المواقف.)

في بعض الأحيان، هناك قطعتان من المعلومات التي تقوم دائمًا بتمريرها معًا، سواء كمعلمة، أو قيمة إرجاع، أو أي شيء آخر.بالتأكيد، يمكنك كتابة العنصر الخاص بك، ولكن إذا كان مجرد عنصرين أوليين صغيرين أو ما شابه ذلك، في بعض الأحيان يبدو الزوج جيدًا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top