2012-02-05 9 views
21

कच्चे पॉइंटर्स के बजाय कंटेनर के टेम्पलेट पैरामीटर के रूप में std::reference_wrapper का उपयोग किस लाभ से किया गया है? यही कारण है कि std::vector<std::reference_wrapper<MyClass> > बनाम std::vector<MyClass*>कंटेनरों में कच्चे सूचक के बजाय context_wrapper का उपयोग करने के लाभ?

मैं nulls के बारे में भूल जाते हैं और नहीं सूचक सिंटैक्स का उपयोग करने के लिए पसंद है, लेकिन प्रकार के शब्दाडंबर (यानी vector<reference_wrapper<MyClass> >) प्लस कॉल साइट उपयोग std :: रैप करने के लिए वास्तविक संदर्भ मुझे बनाता रेफरी चल रहा है लगता है कि यह इसके लायक नहीं है।

मैं उन मामलों का जिक्र कर रहा हूं जिनमें std :: shared_ptr या किसी अन्य स्मार्ट पॉइंटर का उपयोग करना एक विकल्प नहीं है।

क्या संदर्भ_वापर या किसी अन्य कारक का उपयोग करने के अन्य लाभ हैं जिन्हें मैं वर्तमान में ध्यान में नहीं ले रहा हूं? (मुझे लगता है कि मेरा प्रश्न सी ++ 11 के संदर्भ_वापर और बूस्ट दोनों पर लागू होता है)

+5

आईएमओ, संदर्भ गैर-शून्यता एक बड़ा लाभ है, जो अक्सर शब्दशः से अधिक है। लेकिन यह सिर्फ एक अनुभवी नल-नफरत की राय है। – kkm

+0

@kkm यह तर्क अभी भी [not_null] के साथ है (https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#i12-declare-a-pointer-that-must-not-be-null -as-not_null) पॉइंटर्स? – Woofas

+0

@Woofas: शायद नहीं। मैं नवीनतम भाषा प्रस्तावों से बहुत परिचित नहीं हूं। यह एक whoppin '3 दिनों के लिए बाहर गया है! :) – kkm

उत्तर

18

मुझे नहीं लगता कि तकनीकी अंतर है। संदर्भ रैपर गतिशील रूप से लक्ष्य को बदलने की क्षमता सहित मूल सूचक कार्यक्षमता प्रदान करता है।

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

+1

अनुवांशिक - संदर्भ/ref_wrappers ऑब्जेक्ट आजीवन मुद्दों को नहीं रोकते हैं, भले ही उनका वाक्यविन्यास पॉइंटर्स से बेहतर है। – mskfisher

+0

हां, यह वास्तव में इरादे के बारे में है। मैं जोड़ता हूं कि संदर्भ गैर-शून्य पॉइंटर्स हैं। 'std :: vector 'इसमें एक नलप्टर हो सकता है, जबकि संदर्भों के वेक्टर पर पुनरावृत्ति करते समय, आप जानते हैं कि उन सभी को वैध माना जाना चाहिए। –

0

सी संदर्भ टेम्पलेट्स के साथ काम करते समय वास्तव में समस्याग्रस्त हैं। आप "भाग्यशाली" पर्याप्त टेम्पलेट पैरामीटर आपको लगता है कि (किसी कारण के लिए) काम करेगा कोड के साथ समस्याएं हो रही हों के रूप में संदर्भ के साथ कोड को संकलित करने हैं, तो इस प्रकार है:

template<class T> f(T x) { g(x); } 
template<class T> g(T x) { x++; } 

फिर भले ही आप फोन f<int&>(x) यह g<int> कॉल करेंगे । लेकिन reference_wrapper टेम्पलेट्स के साथ ठीक काम करता है।

जैसा कि पहले भी उल्लेख किया गया है - आपको vector<int&> जैसी चीजों को संकलित करने में समस्या होगी, लेकिन vector<reference_wrapper<int>> ठीक काम करता है।

+0

"फिर भी यदि आप' f (x) 'कहें तो यह 'g ' कॉल करेगा। हाँ, मुझे लगता है कि ऐसा इसलिए है क्योंकि आपने 'f() 'को अग्रेषण संदर्भ के रूप में तर्क नहीं दिया और फिर' std :: forward' को 'g()' पर ले लिया। मुझे लगता है कि अगर आपने ऐसा किया है, तो आप यह काम कर सकते हैं। यदि ऐसा है, तो कोडिंग के दौरान एक कदम गुम हो जाता है जब भाषा "वास्तव में समस्याग्रस्त" नहीं होती है। ;-) –

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