2010-06-25 20 views
17

में सभी रचनाकारों को अग्रेषित करना सी ++ 0x में सभी माता-पिता के रचनाकारों को आगे बढ़ाने का सही तरीका क्या है?सी ++ 0x

मैं यह कर दिया गया है:

class X: public Super { 
    template<typename... Args> 
     X(Args&&... args): Super(args...) {} 
}; 
+0

क्या टेम्पलेट शॉर्ट-कट का उपयोग करने के बजाय सभी रचनाकारों को टाइप करने का कोई कारण है? –

+10

हां, समय, और यदि सुपर क्लास अपडेट किया गया है, तो वह रखरखाव की गड़बड़ी में होगा। स्वचालित समाधान असीम रूप से बेहतर है। – Puppy

+1

@DeadMG - वास्तव में नहीं। तो क्या होगा अगर आधार को नया कन्स्ट्रक्टर मिल जाए? व्युत्पन्न इसे तब तक उपयोग करने की आवश्यकता नहीं है जब तक कि नई जानकारी की आवश्यकता न हो। इस बिंदु पर यह स्वचालित "समाधान" स्वचालित रूप से व्युत्पन्न सभी ग्राहकों के साथ इस से निपटने को रोकता है। अक्सर यह करने के लिए पूरी तरह गलत बात नहीं है। व्युत्पन्न तब तक अपडेट नहीं किया जाना चाहिए जब तक कि ऐसी कोई वस्तु न हो जिसे इसकी आवश्यकता होती है और इसे स्पष्ट रूप से किया जाना चाहिए ताकि यह स्पष्ट हो कि यह उसके कन्स्ट्रक्टर को देखकर ऑब्जेक्ट कैसे बनाया जाए। विविध स्थितियों के लिए रिजर्व विविध टेम्पलेट्स। –

उत्तर

39

इस

class X: public Super { 
    using Super::Super; 
}; 

के लिए C++ 0x में एक बेहतर तरीका आप एक आदर्श अग्रेषण टेम्पलेट, अपने प्रकार अधिभार संकल्प में बुरी तरह से व्यवहार करेंगे की घोषणा तो है। कल्पना कीजिए कि आपके आधार वर्ग int से परिवर्तनीय है और कक्षाओं

class Base { 
public: 
    Base(int n); 
}; 

class Specific: public Base { 
public: 
    template<typename... Args> 
    Specific(Args&&... args); 
}; 

void printOut(Specific const& b); 
void printOut(std::string const& s); 

आप के साथ

printOut("hello"); 

क्या कहा जाएगा इसे कहते प्रिंट करने की दो कार्यों वहाँ मौजूद हैं? यह संदिग्ध है, क्योंकि Specific चरित्र सरणी सहित किसी भी तर्क को परिवर्तित कर सकता है। यह मौजूदा बेस क्लास कन्स्ट्रक्टर के संबंध में करता है। घोषणाओं का उपयोग करने वाले कन्स्ट्रक्टरों को केवल इन कन्स्ट्रक्टरों को घोषित करें जो इस काम को करने के लिए आवश्यक हैं।

+0

आईएमएचओ - यह वह उत्तर है जिसे स्वीकार किया जाना चाहिए था, भले ही अन्य सीधे पूछे गए प्रश्न का उत्तर दें। –

+0

धन्यवाद जोहान्स। @ नोहा रॉबर्ट्स: हाँ। –

+1

मैं बस सोच रहा हूं कि 'स्पष्ट' कीवर्ड कॉल को स्पष्ट नहीं करेगा जबकि एक ही समय में पूर्ण अग्रेषण टेम्पलेट को काम करने की अनुमति होगी। ऐसा नहीं है कि मैं स्वचालित रूप से व्युत्पन्न रचनाकारों को उत्पन्न करने की अनुशंसा करता हूं ... –

5

मुझे लगता है कि आप Super(std::forward<Args>(args)...) करने के लिए अगर आप ठीक ढंग से अग्रेषित चीजें चाहते हैं की जरूरत है। args का नाम है, इसलिए मेरा मानना ​​है कि यह रावल संदर्भों से पहले नियमित संदर्भों से जुड़ा होगा।

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

+1

'सुपर (std :: आगे (तर्क) ...) 'सही है, तो आप बहुत करीब थे। याद रखें, आगे स्पष्ट टेम्पलेट तर्क की आवश्यकता है। – Puppy

+0

मैंने मूल रूप से यह किया था, तो मैंने दूसरी बार खुद का अनुमान लगाया।सुधारों के लिए धन्यवाद। –

+0

यह बहुत अच्छा है। क्या आपके पास अंतर्ज्ञान है कि std :: आगे क्या करता है? (क्या यह पहला ऑर्डर है?) हम सिर्फ "तर्क ..." क्यों नहीं लिख सकते? क्या परिणामस्वरूप रचनाकारों को कॉपी किया जा रहा है? –