ما هو الأمراض المنقولة جنسيا::زوج؟
سؤال
ما هو std::pair
لماذا سأستخدمه، وما هي فوائده boost::compressed_pair
يحضر؟
المحلول
std::pair
هو نوع بيانات لتجميع قيمتين معًا ككائن واحد. std::map
يستخدمه لأزواج المفاتيح والقيمة.
بينما كنت تتعلم pair
, ، يمكنك التحقق من ذلك tuple
.انها مثل pair
ولكن لتجميع عدد تعسفي من القيم. tuple
هو جزء من TR1 والعديد من المترجمين يدرجونه بالفعل مع تطبيقات المكتبة القياسية الخاصة بهم.
راجع أيضًا الفصل الأول "الصفوف" من الكتاب ملحقات مكتبة C++ القياسية:البرنامج التعليمي والمرجع بقلم بيت بيكر، ISBN-13:9780321412997 للتوضيح الشامل.
نصائح أخرى
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>
- لذلك يمكن تحديد الخوارزميات التي تقبل كائنًا واحدًا يمثل النطاق بدلاً من تكرارين منفصلين.(إنه بديل مفيد في العديد من المواقف.)
في بعض الأحيان، هناك قطعتان من المعلومات التي تقوم دائمًا بتمريرها معًا، سواء كمعلمة، أو قيمة إرجاع، أو أي شيء آخر.بالتأكيد، يمكنك كتابة العنصر الخاص بك، ولكن إذا كان مجرد عنصرين أوليين صغيرين أو ما شابه ذلك، في بعض الأحيان يبدو الزوج جيدًا.