2008-09-18 16 views

उत्तर

34

std::pair एक ही वस्तु के रूप में दो मानों को एक साथ समूहित करने के लिए एक डेटा प्रकार है। std::map कुंजी, मूल्य जोड़े के लिए इसका उपयोग करता है।

जबकि आप pair सीख रहे हैं, तो आप tuple देख सकते हैं। यह pair जैसा है लेकिन मूल्यों की मनमानी संख्या को समूहित करने के लिए। tuple TR1 का हिस्सा है और कई कंपाइलर्स पहले से ही इसे अपने मानक लाइब्रेरी कार्यान्वयन के साथ शामिल करते हैं।

इसके अलावा, चेकआउट अध्याय 1, "tuples," किताब की सी ++ स्टैंडर्ड लाइब्रेरी एक्सटेंशन: एक ट्यूटोरियल और संदर्भ पीट बेकर, ISBN-13 द्वारा: 9780321412997, एक संपूर्ण विवरण के लिए।

alt text http://ak.buy.com/db_assets/prod_images/225/202452225.jpg

+1

इसके अलावा, यदि आपके कंपाइलर ने अभी तक TR1 का समर्थन नहीं किया है, तो बूस्ट लाइब्रेरीज़ में टुपल्स का अच्छा कार्यान्वयन होता है। –

11

आपको कभी-कभी किसी फ़ंक्शन से 2 मान वापस करने की आवश्यकता होती है, और यह अक्सर इसके लिए कक्षा बनाने के लिए अधिक होता है।

std: जोड़ी उन मामलों में काम में आती है।

मुझे लगता है कि बढ़ावा: compressed_pair आकार 0 के सदस्यों को अनुकूलित करने में सक्षम है। जो पुस्तकालयों में भारी टेम्पलेट मशीनरी के लिए अधिकतर उपयोगी है।

यदि आप सीधे प्रकारों को नियंत्रित करते हैं, तो यह अप्रासंगिक है।

+3

और आप "ए, बी = func();" अनुमानित कोड लिखने के लिए बूस्ट :: टाई का उपयोग कर सकते हैं। स्पष्ट रूप से एक जोड़ी को तुरंत चालू करने के बजाय, आप लिखते हैं: "boost :: टाई (ए, बी) = func();"। – rlerallut

3

std :: जोड़ी एसटीएल में कुछ अन्य कंटेनर कक्षाओं के लिए आसान है।

उदाहरण के लिए:

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

दोनों दुकान std :: कुंजी और मूल्यों के जोड़े।

मानचित्र और मल्टीमैप का उपयोग करते समय, आप अक्सर एक जोड़ी को पॉइंटर का उपयोग करके तत्वों तक पहुंचते हैं।

3

मूल्यों की एक जोड़ी संग्रहीत करने के लिए यह मानक वर्ग है। यह std::map::insert जैसे कुछ मानक कार्यों द्वारा वापस/उपयोग किया जाता है।

boost::compressed_pair दावों अधिक कुशल होने का: see here

1

कभी-कभी लगता है कि तुम सिर्फ हमेशा कि क्या एक पैरामीटर है, या एक वापसी मान, या जो कुछ भी रूप में एक साथ चारों ओर गुजरती हैं, जानकारी के दो टुकड़े कर रहे हैं। निश्चित रूप से, आप अपनी खुद की वस्तु लिख सकते हैं, लेकिन यदि यह केवल दो छोटे प्राइमेटिव या समान है, तो कभी-कभी एक जोड़ी ठीक लगती है।

3

अतिरिक्त जानकारी: को बढ़ावा देने :: compressed_pair उपयोगी होता है जब जोड़ी के प्रकारों में से एक एक खाली struct है। यह अक्सर टेम्पलेट मेटाप्रोग्रामिंग में उपयोग किया जाता है जब जोड़ी के प्रकार प्रोग्रामेटिक रूप से अन्य प्रकार से अनुमानित होते हैं। अंत में, आपके पास आमतौर पर "खाली संरचना" का कुछ रूप होता है।

मैं किसी भी "सामान्य" उपयोग के लिए std :: जोड़ी पसंद करूंगा, जब तक कि आप भारी टेम्पलेट मेटाप्रोग्रामिंग में न हों।

3

यह हुड के नीचे दो चर के साथ एक संरचना के अलावा कुछ भी नहीं है।

मैं वास्तव में फ़ंक्शन रिटर्न के लिए std :: जोड़ी का उपयोग करके नापसंद करता हूं। कोड के पाठक को यह जानना होगा कि क्या।पहला है और क्या। सेकेंड है।

मैं कभी-कभी समझौता करता हूं कि संदर्भों को स्पष्ट रूप से संदर्भित करते समय, पहले और .second के निरंतर संदर्भ बनाना है।

+1

मैं नामकरण सम्मेलन के बारे में आपसे सहमत हूं। रखरखाव कठिन बनाता है। – Adam

80

compressed_pair अंतरिक्ष बचाने के लिए कुछ टेम्पलेट ट्रिकरी का उपयोग करता है। सी ++ में, एक ऑब्जेक्ट (छोटा ओ) एक अलग ऑब्जेक्ट के समान पता नहीं हो सकता है।

तो भले ही आप

struct A { }; 

A के आकार 0 होगा नहीं, क्योंकि तब:

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

पकड़ होता है, जिसकी अनुमति नहीं है।

लेकिन कई compilers क्या "खाली आधार वर्ग अनुकूलन" कहा जाता है क्या करेंगे:

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

यहाँ, यह B और C के लिए ठीक है, एक ही आकार के लिए भले ही sizeof(A) नहीं कर सकते शून्य हो।

तो boost::compressed_pair इस अनुकूलन का लाभ उठाता है और जहां संभव हो, जोड़ी में एक या दूसरे प्रकार के प्रकार से प्राप्त होता है, यदि यह खाली है।

तो एक std::pair की तरह (मैं एक अच्छा सौदा, ctors आदि elided है) दिख सकता है:

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

इसका मतलब है कि यदि या तो FirstType या SecondTypeA है, अपने 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) रूप में बड़ा हो जाएगा।

+3

अच्छा उत्तर दोस्त :) –

+0

बस इस सोच को पढ़ रहा था, इस आदमी का जवाब डर गया और पूरा हो गया, और फिर महसूस किया कि यह कौन था, और थोड़ा आश्चर्य भी नहीं था! हे लोगान! –

+0

क्या मुझे कुछ महत्वपूर्ण याद आया है? कृपया मुझे बताओ, यह आदमी कौन है? मैं उसे भी प्रशंसा देना चाहता हूं :) –

11

यह सुनकर अजीब लग सकता है कि संपीड़ित_पैयर कुछ बाइट्स की परवाह करता है। लेकिन यह वास्तव में महत्वपूर्ण हो सकता है जब कोई समझता है कि संपीड़ित_पैयर का उपयोग किया जा सकता है। उदाहरण के लिए चलिए इस कोड पर विचार करें:

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

यह अचानक ऊपर के मामलों में संपीड़ित_पैयर का उपयोग करने के लिए एक बड़ा प्रभाव हो सकता है। क्या हो सकता है यदि बूस्ट :: बाइंड फ़ंक्शन पॉइंटर और प्लेस धारक _1 को स्वयं के सदस्यों के रूप में या std::pair में स्वयं के रूप में संग्रहीत करता है? खैर, यह sizeof(&f) + sizeof(_1) तक फूट सकता है। एक फ़ंक्शन पॉइंटर मानते हुए 8 बाइट्स (विशेष रूप से सदस्य फ़ंक्शंस के लिए असामान्य नहीं हैं) और प्लेसहोल्डर के पास एक बाइट है (क्यों लॉगन का जवाब देखें), तो हमें बाइंड ऑब्जेक्ट के लिए 9 बाइट्स की आवश्यकता हो सकती थी। संरेखित होने के कारण, यह एक सामान्य 32 बिट सिस्टम पर 12 बाइट तक फूट सकता है।

boost::function एक छोटे ऑब्जेक्ट अनुकूलन को लागू करने के लिए इसके कार्यान्वयन को प्रोत्साहित करता है। इसका मतलब है कि छोटे फ़ैक्टर के लिए, boost::function ऑब्जेक्ट में सीधे एम्बेडेड एक छोटा बफर मज़ेदार को स्टोर करने के लिए उपयोग किया जाता है। बड़े मज़दूरों के लिए, ढेर को स्मृति प्राप्त करने के लिए ऑपरेटर का उपयोग करके उपयोग करना होगा।version 1.34 को बढ़ावा देने के लिए, this optimization को अपनाने का निर्णय लिया गया था, क्योंकि यह अनुमान लगाया गया था कि कोई बहुत ही शानदार प्रदर्शन लाभ प्राप्त कर सकता है।

अब, ऐसे छोटे बफर के लिए एक उचित (अभी तक, शायद अभी भी छोटी) सीमा 8 बाइट होगी। यही है, हमारी काफी सरल बाइंड ऑब्जेक्ट छोटे बफर में फिट नहीं होगी, और ऑपरेटर को नए स्टोर करने की आवश्यकता होगी। यदि उपरोक्त बाइंड ऑब्जेक्ट compressed_pair का उपयोग करेगा, तो यह वास्तव में इसके आकार को 8 बाइट्स (या गैर-सदस्य फ़ंक्शन पॉइंटर के लिए 4 बाइट्स) को कम कर सकता है, क्योंकि प्लेसहोल्डर एक खाली ऑब्जेक्ट से अधिक कुछ नहीं है।

तो, केवल कुछ बाइट्स के लिए बहुत सारे विचारों को बर्बाद करने जैसा लगता है वास्तव में प्रदर्शन पर महत्वपूर्ण प्रभाव हो सकता है।

2

std :: जोड़ी क्या है, मैं इसका उपयोग क्यों करूं?

यह उतना आसान है जितना सरल दो तत्व tuple। इसे STL के पहले संस्करण में परिभाषित किया गया था जब संकलक टेम्पलेट्स और मेटाप्रोग्रामिंग तकनीकों का व्यापक रूप से समर्थन नहीं कर रहे थे, जिन्हें Boost.Tuple जैसे अधिक परिष्कृत प्रकार के ट्यूपल को लागू करने की आवश्यकता होगी।

यह कई स्थितियों में उपयोगी है। मानक सहयोगी कंटेनरों में std::pair का उपयोग किया जाता है। इसे std::pair<iterator, iterator> श्रेणी के एक साधारण रूप के रूप में उपयोग किया जा सकता है - इसलिए कोई भी दो इटरेटर्स की बजाय रेंज का प्रतिनिधित्व करने वाले एकल ऑब्जेक्ट को स्वीकार करने वाले एल्गोरिदम को परिभाषित कर सकता है। (यह कई स्थितियों में एक उपयोगी विकल्प है।)

संबंधित मुद्दे