2011-07-20 21 views
22

explicit कीवर्ड के लिए सिफारिश की है सभी सबसे कंस्ट्रक्टर्स जो एक तर्क साथ कहा जा सकता है, कॉपी निर्माताओं के लिए छोड़कर।स्पष्ट चाल कन्स्ट्रक्टर?

प्रतिलिपि कंस्ट्रक्टर्स के लिए, यह एक का उपयोग करें (समारोह कॉल, वापसी, आदि के माध्यम से निहित नकल न करे करने के लिए) है, लेकिन यह क्या आम तौर पर चाहता था है नहीं है।

चालक के बारे में क्या? क्या उन्हें स्पष्ट करने के लिए कोई उचित उपयोग केस है? यहाँ अच्छा अभ्यास क्या है?

+0

"कॉपी कन्स्ट्रक्टर" और "कन्स्ट्रक्टर जिसे एक तर्क के साथ बुलाया जा सकता है" के बीच क्या अंतर है? मेरे पास डेडएमजी के जवाब के साथ कुछ क्षण भ्रम था क्योंकि मैंने सोचा था कि ये वही बात थीं। यह * है * जिस तरह से इसका उपयोग किया जाता है, और ("स्पष्ट" के अलावा) नहीं कि कन्स्ट्रक्टर को कैसे घोषित किया जाता है, हां? या मैं पागल हो गया है? – Steve314

+3

@ स्टीव 314: एक एकल-तर्क प्रतिलिपि निर्माता विशेष रूप से एक कन्स्ट्रक्टर 'टी ([कॉन्स] [अस्थिर] टी एंड)' है। 12.8/2। 'टी (इंट)' एक कन्स्ट्रक्टर है जिसे एक तर्क के साथ बुलाया जा सकता है, लेकिन यह एक कॉपी कन्स्ट्रक्टर नहीं है क्योंकि यह 'टी' के उदाहरण को" कॉपी "नहीं करता है। –

+0

@ स्टेव जेसॉप - हां, ज़ाहिर है। जाहिर है मैं मस्तिष्क मर गया है। – Steve314

उत्तर

19

एक explicit चालक निर्माता संगतता को प्रभावित कर सकते हैं उदा। मानक एल्गोरिदम। उदाहरण के लिए, std::swap<T> की आवश्यकता है कि T MoveConstructible हो। बदले में, MoveConstructible को अभिव्यक्ति के संदर्भ में निर्दिष्ट किया गया है, अर्थात् T u = rv; (जहां rvT प्रकार का एक रावल्यू है)।

यदि वहाँ न तो एक गैर स्पष्ट प्रतिलिपि निर्माता है और न ही किसी दिए गए प्रकार के लिए एक गैर स्पष्ट कदम निर्माता तो T u = rv; अमान्य है और उस प्रकार std::swap साथ नहीं किया जा सकता है। (इस विशेष उदाहरण में वांछित कार्यक्षमता प्रदान करने के लिए std::swap विशेषज्ञता देना संभव है, उदाहरण के लिए T u(rv); का उपयोग करके)।

अधिक आसानी से रखें, explicit चालक या प्रतिलिपि बनाने वाले प्रतिलिपि उम्मीदों को खारिज करते हैं और सामान्य कोड के साथ भी इसका उपयोग नहीं किया जा सकता है।

स्टैंडर्ड पुस्तकालय है कि एक MoveConstructible आवश्यकता डाल के कुछ अन्य भाग:

  • unique_ptr<T, D>
  • कॉल रैपर की Deleter, उदा में इस्तेमाल किया bind (सभी सड़ा हुआ प्रकार है कि पारित कर रहे हैं चिंतित हैं)
  • thread, async, call_once (कॉल रैपर के मामले में सभी निर्दिष्ट)
  • sort, stable_sort, nth_element, sort_heap
5

आप शायद अधिकांश उपयोगों के लिए एक निहित चालक निर्माता चाहते हैं। वे आम तौर पर कॉपी कन्स्ट्रक्टर के समान श्रेणियों में आते हैं। सभी एक-तर्क कन्स्ट्रक्टर के लिए स्पष्ट अनुशंसा नहीं की जाती है, लेकिन अधिकांश के लिए इसकी अनुशंसा की जाती है। ले जाएं कन्स्ट्रक्टर उस सूची में नहीं हैं।

5

explicit कीवर्ड की सिफारिश की है अप्रत्याशित स्थानों में आश्चर्यजनक रूपांतरणों से बचने के लिए, (एकल तर्क) कन्वर्टर कनवर्ट करना।

रचनाकारों की प्रतिलिपि बनाएँ और रचनाकारों को स्थानांतरित करना मुश्किल से "आश्चर्यजनक" है। वे बड़े पैमाने पर जहां अपेक्षा की जाती है। यदि आप उन्हें नहीं चाहते हैं, तो मैं उन्हें स्पष्ट करने के बजाय =delete चिह्नित करने की अपेक्षा करता हूं।

2

वास्तविक सवाल यह है कि कैसे स्पष्ट चालक का उपयोग संभवतः किया जा सकता है? यह रावजू पर लागू नहीं किया जा सकता है, इसलिए कंपाइलर को हमेशा एक प्रतिलिपि बनाने का चयन करना होगा, अगर उपलब्ध हो, या संकलित करने में असफल हो।

संपादित करें: http://www.ideone.com/nm7KM

+0

[प्रत्यक्ष प्रारंभिकरण का उपयोग] (http://www.ideone.com/W2BT3)। –

+0

@Luc: यह एक अच्छा है! और शायद एकमात्र तरीका स्पष्ट चालक कन्स्ट्रक्टर को बुलाया जा सकता है। –

+0

+1 एक अच्छे प्रश्न के लिए, जीन :) और उत्तर के लिए ल्यूक के लिए अधिक प्रोप (यह उपयोगी हो सकता है यदि आप इसे किसी भी भविष्य के संदर्भ के लिए अपनी पोस्ट में जोड़ देंगे)। धन्यवाद! – Kos

0

जब एक समारोह से मूल्य से लौटने, एक अंतर्निहित चाल निर्माता आमतौर पर प्रक्रिया को और अधिक कुशल बनाने के कर सकते हैं: यहाँ उदाहरण के लिए लिंक है।

+0

थोड़ा सा विषय-वस्तु लेकिन अच्छा बिंदु, असल में- मुझे लगता है कि यदि संभव हो तो कन्स्ट्रक्टर इनलाइन को स्थानांतरित करने का एक कारण है। – Kos

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