2010-06-01 4 views
26

क्या विविध रचनाकारों को अंतर्निहित जेनरेट किए गए लोगों को छिपाना है, यानी डिफ़ॉल्ट कन्स्ट्रक्टर और कॉपी कन्स्ट्रक्टर?क्या विविध रचनाकारों को अंतर्निहित जनरेटरों को छिपाना चाहिए?

struct Foo 
{ 
    template<typename... Args> Foo(Args&&... x) 
    { 
     std::cout << "inside the variadic constructor\n"; 
    } 
}; 

int main() 
{ 
    Foo a; 
    Foo b(a); 
} 

किसी तरह मैं इस this answer पढ़ने के बाद कुछ भी नहीं मुद्रित करने के लिए उम्मीद कर रहा था, लेकिन यह जी ++ 4.5.0 पर दो बार inside the variadic constructor प्रिंट :(इस व्यवहार सही है


यह भी variadic टेम्पलेट्स के बिना होता है?:

struct Foo 
{ 
    Foo() 
    { 
     std::cout << "inside the nullary constructor\n"; 
    } 

    template<typename A> Foo(A&& x) 
    { 
     std::cout << "inside the unary constructor\n"; 
    } 
}; 

int main() 
{ 
    Foo a; 
    Foo b(a); 
} 

फिर, दोनों लाइनों मुद्रित कर रहे हैं।

+1

मैंने अभी gcc45 पर एक त्वरित परीक्षण चलाया है, और एक नियमित, गैर-चरणीय टेम्पलेट कन्स्ट्रक्टर एक संकलक उत्पन्न डिफॉल्ट कन्स्ट्रक्टर के निर्माण को रोकता है। मेरा संदेह यह है कि नियम सी ++ 0x में बदल गए हैं। –

+2

@Dennis: मैं अगर C++ 0x नियम है कि C++ 0x के साथ पेश किया जाएगा बदल जाएगा _really_ आश्चर्य होगा। ':)' – sbi

+0

@ डेनिस तो क्या जुड़ा हुआ उत्तर फर्जी है? यह कहता है "एक टेम्पलेट कन्स्ट्रक्टर या असाइनमेंट ऑपरेटर संकलित जनरेटर को दबाने नहीं देगा"। – fredoverflow

उत्तर

19

निहित रूप से घोषित प्रतिलिपि निर्माता की घोषणा वास्तव में दबाने वाली नहीं है। इसे अधिभार संकल्प के नियमों के कारण बुलाया नहीं जा रहा है।

निहित रूप से घोषित प्रतिलिपि निर्माता का फॉर्म Foo(const Foo&) है। इसका महत्वपूर्ण हिस्सा यह है कि यह एक कॉन्स्ट संदर्भ लेता है। आपका कन्स्ट्रक्टर टेम्पलेट एक गैर-कॉन्स्ट संदर्भ लेता है।

a कॉन्स नहीं है, इसलिए गैर-कॉन्स्ट उपयोगकर्ता द्वारा घोषित कन्स्ट्रक्टर टेम्पलेट को पूरी तरह से घोषित प्रतिलिपि निर्माता पर प्राथमिकता दी जाती है। परोक्ष-घोषित प्रतिलिपि निर्माता फोन के लिए, आपको a स्थिरांक बना सकते हैं:

const Foo a; 
Foo b(a); 

या आप static_cast का उपयोग a करने के लिए एक स्थिरांक संदर्भ प्राप्त करने के लिए कर सकते हैं:

Foo a; 
Foo b(static_cast<const Foo&>(a)); 

अधिभार संकल्प कहता है कि इन का वर्णन कर रहे हैं सी ++ 0x एफसीडी के ज्यादातर §13.3.3.2/3 में पाया गया। यह विशेष रूप से परिदृश्य, lvalue और rvalue संदर्भ के संयोजन के साथ, एक तरह से पेज 303.


एक variadic निर्माता टेम्पलेट परोक्ष घोषित डिफ़ॉल्ट निर्माता को दबाने होगा पर विभिन्न उदाहरणों द्वारा वर्णित है, क्योंकि एक variadic निर्माता टेम्पलेट उपयोगकर्ता है -declared और अगर कोई उपयोगकर्ता के घोषित कंस्ट्रक्टर्स (C++ 0x FCD §12.1/5) कर रहे हैं परोक्ष घोषित डिफ़ॉल्ट निर्माता केवल प्रदान की जाती है:

अगर वहाँ वर्ग X के लिए कोई उपयोगकर्ता के घोषित निर्माता, एक कोई पैरामीटर नहीं रखने वाले कन्स्ट्रक्टर को निश्चित रूप से डिफॉल्ट के रूप में घोषित किया जाता है।

एक variadic निर्माता टेम्पलेट परोक्ष घोषित प्रतिलिपि निर्माता को दबाने नहीं करेगा क्योंकि केवल एक गैर टेम्पलेट निर्माता एक प्रति निर्माता हो सकता है (C++ 0x FCD §12.8/2, 3, और 8):

वर्ग X के लिए एक गैर टेम्पलेट निर्माता अगर इसकी-सी युक्तियां पैरामीटर प्रकार X&, const X&, volatile X& या const volatile X& की है, और या तो कोई अन्य पैरामीटर वरना सभी अन्य पैरामीटर डिफ़ॉल्ट तर्क है देखते हैं एक प्रति निर्माता है।

वर्ग X के लिए एक गैर टेम्पलेट निर्माता अगर इसकी-सी युक्तियां पैरामीटर प्रकार X&&, const X&&, volatile X&&, या const volatile X&& की है, और या तो कोई अन्य पैरामीटर वरना सभी अन्य पैरामीटर डिफ़ॉल्ट तर्क है देखते हैं एक चाल निर्माता है।

वर्ग डी फाई nition स्पष्ट रूप से एक प्रति निर्माता की घोषणा नहीं करता है और वहाँ कोई उपयोगकर्ता के घोषित चाल निर्माता है, एक प्रति निर्माता परोक्ष रूप चूक घोषित किया जाता है।

+0

@James "टेम्पलेट निर्माता [...] एक प्रति निर्माता कभी नहीं है" -> तो जी ++ 4.5.0 गाड़ी और दूसरी पंक्ति कुछ भी मुद्रित नहीं चाहिए? और एफसीडी द्वारा आपका मतलब n3090 है? – fredoverflow

+0

@Fred: एफसीडी n3092 है; मुझे उद्धरण अपडेट करना पड़ा क्योंकि मेरे पास किसी कारण से n3035 खुला था और n3092 में कुछ बदलाव हुए हैं ... इसके बारे में खेद है। –

+0

@ जेम्स यह गैर-वैरिएड टेम्पलेट्स के साथ भी होता है, मैंने अपना प्रश्न अपडेट किया है! – fredoverflow

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