2011-11-13 17 views
5

एसटीएल कंटेनर एक reference और const_referencetypedef है, जो कई मामलों में मैंने देखा है है (bool जा रहा है केवल अपवाद के कंटेनरों को मैं के बारे में सोच सकते हैं), तुच्छता के रूप में'संदर्भ' टाइपपीफ वास्तव में कैसे व्यवहार करता है?

typedef value_type& reference; 
typedef const value_type& const_reference; 

में परिभाषित किया जा सकता है वास्तव में क्या है, तथापि , अर्थशास्त्र इन प्रकारों में से हैं?

जो मैं समझता हूं उससे, उन्हें "मूल्य प्रकार के संदर्भों की तरह व्यवहार करना" माना जाता है, लेकिन इसका क्या अर्थ है?

MSDN का कहना है कि reference है:

एक प्रकार है कि एक तत्व एक सदिश में संग्रहीत के लिए एक संदर्भ प्रदान करता है।

लेकिन इसका क्या अर्थ है, बिल्कुल? क्या उन्हें विशिष्ट ऑपरेटरों को अधिभारित करने की आवश्यकता है, या एक विशिष्ट व्यवहार है? यदि हां, तो आवश्यक व्यवहार क्या है?

+2

मुझे नहीं लगता कि कोई भी इस प्रश्न को समझ रहा है। वह पूछ रहा है कि जिस प्रकार को "संदर्भ" कहा जाता है, वह व्यवहार करने की ज़रूरत है। सी ++ संदर्भ प्रकार नहीं (जैसे 'int &')। –

+0

दूसरे विचारों पर, मुझे नहीं लगता कि मैं अब क्यू को समझता हूं। प्रकार 'संदर्भ' या 'const_reference' सामान्य संदर्भ या कॉन्स संदर्भ व्यवहार की तरह व्यवहार करता है, आपको ऐसा क्यों लगता है कि इसे किसी भी तरह से व्यवहार करना चाहिए? –

+0

@ एएलएस: सवाल, सचमुच, है: "सामान्य संदर्भ की तरह व्यवहार करता है" का क्या अर्थ है? यह स्वयं ही एक अस्पष्ट वाक्य है, इसलिए मुझे नहीं पता कि मुझे किस प्रकार की शर्तों को "सामान्य संदर्भ की तरह व्यवहार करता है" से पहले संतुष्ट करने की आवश्यकता होगी (यदि मैं कंटेनर बना रहा हूं, उदाहरण के लिए)। – Mehrdad

उत्तर

1

क्या आप पूछ रहे हैं "कर सकता हूँ मैं हमेशा एक संदर्भ भिन्नता है? और हाँ, आप कर सकते हैं। यही कारण है कि इसका मतलब है dereferenced reference सब कुछ dereferenced value_type& सब कुछ value_type कर सकते हैं जो कर सकते हैं। यह है कि आप करने के लिए समझ में आता है, तो कर सकते हैं।


आप ऑपरेटरों typedefs पर ओवरलोड नहीं कर सकते। typedefs प्रकार वे को सौंपा है। कारण वे कर रहे हैं typedef'd उन्हें कम बोझिल बनाने के लिए और एक आम "इंटरफेस"

प्रदान करना है के रूप में ही व्यवहार

कारण reference मौजूद है इस तरह बातें रोकने के लिए:

template<typename T> 
struct foo { 
    T& bar(); 

    typedef T& reference; 
    reference baz(); 
} 

foo<int> x; 
foo<int>::T& y = x.bar(); // error! returns a T& but I can't create one! 
foo<int>::reference z = x.baz(); // ok! 

यह भी एक क्लीनर इंटरफेस बनाता है और SFINAE के उपयोग की अनुमति देता है:

template<typename T> 
typename T::reference second(T::reference& t) { return t.at(1); }; 

template<typename T> 
T& second(T& t) { return t[1]; }; 

std::vector v(10); 
foo f(10); // type with [] overloaded but no reference typedef 
second(x) = 5; // calls first def 
second(f) = 3; // calls second def 
+1

क्षमा करें, लेकिन मुझे लगता है कि आप इस प्रश्न को याद करते हैं। मैं पूछ रहा था कि 'संदर्भ' प्रकार का ऑपरेटर/फीचर्स किस प्रकार समर्थन कर सकता है ... यह नहीं कि मैं वहां क्या अधिभारित कर सकता हूं या नहीं ... मुझे पहले से ही पता है कि 'टाइपिफ़' कैसे काम करता है और उन्होंने अमूर्तता क्यों शुरू की, आदि; मैं सिर्फ यह जानना चाहता हूं कि मानक के अनुसार 'संदर्भ' को क्या संतुष्ट करना चाहिए। – Mehrdad

+0

@ मेहरदद 'संदर्भ 'सबकुछ कर सकता है' value_type & 'ऐसा कर सकता है जो सब कुछ' value_type' कर सकता है। – Pubby

+1

फिर 'संदर्भ' का उपयोग करने का क्या मतलब है जब आप केवल 'value_type' 'का उपयोग कर सकते हैं, यदि वे एक ही चीज़ हैं? वहां * आवश्यक और पर्याप्त स्थितियों का एक सेट होना चाहिए जो संदर्भ को संतुष्ट करना चाहिए, जो निश्चित रूप से * नहीं * सब कुछ है ... – Mehrdad

4

मुझे लगता है कि सवाल का हिस्सा एक धारणा है कि allocators उपयोगी होते हैं से आता है। Allocators (कम से कम पूर्व सी ++ 11) were something of a late addition to the STL:

लोग स्मृति मॉडल है, जो कुछ हद तक अत्यधिक था, क्योंकि भाषा स्मृति मॉडल शामिल नहीं है की स्वतंत्र कंटेनर चाहता था। लोग पुस्तकालय चाहते थे कि स्मृति मॉडल को सारणीबद्ध करने के लिए कुछ तंत्र प्रदान करें। एसटीएल के पहले संस्करणों ने माना कि कंटेनर का आकार टाइप size_t के पूर्णांक के रूप में व्यक्त किया जा सकता है और दो इटरेटर के बीच की दूरी ptrdiff_t प्रकार है। और अब हमें बताया गया था, आप उससे क्यों अमूर्त नहीं हैं? यह एक लंबा आदेश है क्योंकि भाषा उस से अमूर्त नहीं है; सी और सी ++ सरणी इन प्रकारों द्वारा पैरामीटर नहीं हैं। हमने "आवंटक" नामक एक तंत्र का आविष्कार किया, जो स्मृति मॉडल के बारे में जानकारी को समाहित करता है। इसने पुस्तकालय में हर घटक के लिए गंभीर परिणाम पैदा किए। आपको आश्चर्य हो सकता है कि मेमोरी मॉडल को एल्गोरिदम या कंटेनर इंटरफेस के साथ क्या करना है। यदि आप size_t जैसी चीजों का उपयोग नहीं कर सकते हैं, तो आप अलग-अलग सूचक प्रकार (T*, T huge * इत्यादि) के कारण T* जैसी चीजों का भी उपयोग नहीं कर सकते हैं। फिर आप संदर्भों का उपयोग नहीं कर सकते क्योंकि विभिन्न मेमोरी मॉडल के साथ आपके पास अलग-अलग संदर्भ प्रकार हैं। पुस्तकालय पर जबरदस्त ramifications थे।

दुर्भाग्य से, they turned out to be substandard:

मैं इंटेल की स्मृति वास्तुकला से निपटने के लिए allocators का आविष्कार किया। संकेत दिए गए, संदर्भ, ptrdiff_t, size_t: एक परत है कि सभी स्मृति सामान समाहित होने - वे सिद्धांत रूप में इस तरह के एक बुरा विचारों नहीं हैं। दुर्भाग्य से वे अभ्यास में काम नहीं कर सकते हैं। उदाहरण के लिए,

vector<int, alloc1> a(...); 
vector<int, alloc2> b(...); 

अब आप यह नहीं कह सकते:

find(a.begin(), a.end(), b[1]); 

b[1] रिटर्न एक alloc2::reference और नहीं int&। यह एक प्रकार का मेल नहीं हो सकता है। आवंटकों को वास्तव में उपयोगी बनाने के संदर्भ में कोर भाषा संदर्भों के साथ व्यवहार करने के तरीके को बदलना आवश्यक है।

reference typedef वापस जाने के लिए जो कुछ भी T& के बराबर प्रश्न में संभाजक के लिए है के लिए है। आधुनिक वास्तुकला पर, यह शायद T& है। हालांकि, इस धारणा था कुछ आर्किटेक्चर पर यह कुछ अलग हो सकता है कि (जैसे, एक संकलक के साथ एक वास्तुकला लक्ष्यीकरण "के पास" और "अब तक" संकेत "के पास" और "अब तक" संदर्भ के लिए विशेष सिंटेक्स आवश्यकता हो सकती है)। अफसोस की बात है, यह शानदार विचार कम से कम शानदार साबित हुआ। सी ++ 11 आवंटकों में पर्याप्त परिवर्तन करता है - स्कॉप्ड आवंटकों को जोड़ना - और मेमोरी मॉडल। मुझे स्वीकार करना है कि मुझे सी ++ 11 के बदलावों के बारे में पर्याप्त जानकारी नहीं है w.r.t. कहने के लिए आवंटक अगर चीजें बेहतर या बदतर हो जाती हैं।


मूल प्रश्न पर टिप्पणी को देखते हुए, के बाद से मानक वास्तव में नहीं बताता है कि कैसे कंटेनर लागू किया जाना चाहिए (हालांकि स्टैंडर्ड कि यह हो सकता है और साथ ही कंटेनर के व्यवहार पर इतने सारे आवश्यकताओं डाल दिया है। , प्रकार reference का एक उद्देश्य मूल वस्तु के लिए एक पारदर्शी उर्फ ​​होना चाहिए यह करने के लिए देने की मान बदलना चाहिए: ..), जो कुछ भी आप typedef प्रकार reference रूप T& के व्यवहार कि किसी संभावित जब कंटेनर को लागू करने पर भरोसा कर सकता है होना आवश्यक है टुकड़ा करने की क्रिया के बिना मूल वस्तु, "reseating" reference समर्थन करने के लिए कोई ज़रूरत नहीं, reference का पता लेने ओ का पता लौट जाना है riginal वस्तु, आदि सभी संभव पर है, यह वास्तव में T& होना चाहिए; और केवल मामले मैं कल्पना कर सकते हैं, जहां यह संभव नहीं होगा हो सकता है अगर आप स्मृति है कि आप संकेत या संदर्भ (जैसे के माध्यम से हेरफेर नहीं कर सकता का आवंटन किया गया है, यदि "स्मृति" डिस्क पर वास्तव में थे, या अगर स्मृति वास्तव में थे एक अलग कंप्यूटर पर आवंटित और आरपीसी कॉल, आदि के माध्यम से नेटवर्क पर पहुंच योग्य)।

+0

यह एसटीएल के लिए लगता है, एसटीडी नहीं। – Pubby

+1

"एकमात्र मामला मैं कल्पना कर सकता हूं कि यह संभव नहीं होगा यदि आप स्मृति आवंटित कर रहे थे कि आप पॉइंटर्स या संदर्भों के माध्यम से छेड़छाड़ नहीं कर पाएंगे" मानक आपको वैसे भी आवंटकों को बनाने की अनुमति नहीं देगा, क्योंकि आप नकली नहीं हो सकते सी ++ में एक संदर्भ। आप एक ऑब्जेक्ट संदर्भ sematics नहीं दे सकते हैं। यही कारण है कि 'वेक्टर ' तकनीकी रूप से एक मानक कंटेनर नहीं है। यह 'std :: वेक्टर 'तत्काल के लिए निर्धारित नियमों का पालन नहीं करता है। और ऐसा इसलिए नहीं है क्योंकि आपको 'वेक्टर [3]' करने में सक्षम होना चाहिए, जो 'वेक्टर ' के साथ असंभव है। –

+0

@ पब्बी: एसटीएल मानक से पहले अस्तित्व में था, और यह मानक का हिस्सा बनने पर महत्वपूर्ण रूप से बदल गया था (एक बदलाव यह है कि एल्गोरिदम के 2/3 स्टेपानोव को मूल रूप से हटा दिया गया था)। स्टेपानोव के मुताबिक, सी ++ कुछ तरीकों से बदल दिया गया था जब एसटीएल मानक में अपनाया गया था (एक बदलाव मज़दूरों के अलावा)। उत्तर के अंतिम पैराग्राफ में मेरी टिप्पणियां हैं, मुझे विश्वास है, सी ++ - 98 के लिए केवल "सही" है। सी ++ - 03 ने नियमों को बदल दिया है कि कार्यान्वयन को 'संदर्भ' मानने की अनुमति है, वास्तव में, 'टी &' (आपके उत्तर राज्यों के रूप में, काफी स्पष्ट रूप से)। –

2

मानक से बाहर ले जाया:

enter image description here

यह भी value_type& की एक typedef जो T

की एक typedef है के रूप में परिभाषित करता है reference (पिछले एक के रूप में न्यू जवाब अलग फोकस था)

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