2011-09-12 13 views
23

C++ 0x में, आप तो जैसे, कंस्ट्रक्टर्स वारिस के using कीवर्ड का उपयोग कर सकते हैं:विरासत रचनाकार सी ++ 0x में टेम्पलेट्स के साथ काम करते हैं?

class B { B(int) {} }; 

class A : public B { using B::B; }; 

कौन परोक्ष एक A(int) निर्माता घोषित करेंगे। क्या यह टेम्पलेट्स के साथ काम करता है?

class B { B(int) {} }; 

template<class T> class A : public T { using T::T; }; 

T::T के भीतर, मैं संकलक टेम्पलेट तर्क पर गुंजाइश ऑपरेटर का उपयोग के बाद से बाएं हाथ T यह पता लगाने की उम्मीद सामान्य है, लेकिन पता लगाना है कि दाहिने हाथ T निर्माता है एक विशेष मामला है। असल में ऐसा लगता है कि एक अस्पष्टता है: क्या होगा यदि में T नामक एक विधि है, तो मैं A में अधिभार जोड़ने की कोशिश कर रहा हूं (इस प्रकार एक कंपाइलर इस तरह की घोषणा का उपयोग पूर्व-सी ++ 0x) की व्याख्या करेगा?

उत्तर

10

हां यह काम करता है, और कारण नाम लुकअप तंत्र है। तंत्र विरासत-रचनाकार घोषणा कार्य सरल है: यदि उपयोग घोषणा का नाम बेस क्लास कन्स्ट्रक्टर को संदर्भित करता है, तो यह एक विरासत रचनाकार घोषणा है। 3.4.3.1 पर [class.qual] p2 हम पाते हैं:

एक देखने जिसमें निर्माता एक स्वीकार्य देखने परिणाम और नेस्टेड-नाम-विनिर्देशक है एक C क्लास

  • यदि नामांकित नेस्टेड-नाम-स्पेशल के बाद निर्दिष्ट नाम, सी में देखा जाने पर, सी (क्लॉज 9), या
  • का इंजेक्शन-क्लास-नाम उपयोग-घोषणा (7.3.3) है जो एक सदस्य-घोषणा है , यदि नेस्टेड-नाम-विनिर्देशक के बाद निर्दिष्ट नाम पहचानकर्ता या सरल-टेम्पलेट-आईडी के टेम्पलेट-नाम के समान है, तो नेस्टेड-नाम-विनिर्देशक
  • के अंतिम घटक में

नाम के बजाय वर्ग सी

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

  • पहले बुलेट के ऊपर एक है:

    struct B { 
        B(int) { } 
    }; 
    
    typedef B mytype; 
    
    struct A : B { 
        // "name ... is the same as the identifier ... in the last component ..." 
        using mytype::mytype; 
    }; 
    
    
    template<typename T> using same = T; 
    
    struct C : B { 
        // "name ... is the same as the template-name ... in the last component ..." 
        same<B>::same; 
    }; 
    

    बाद उदाहरण के रूप में निम्नलिखित

    template<template<typename> class Base> 
    struct X : Base<int> { 
        using Base<int>::Base; 
    }; 
    

    सारांश में भी स्थितियों में उपयोगी साबित होता अर्थपूर्ण नियम - यदि नेस्टेड नाम विनिर्देशक के नाम का नाम इंजेक्शन क्लास नाम (B::B या mytype::B) को संदर्भित करता है, तो इसका निर्माण निर्माण के संदर्भ में किया जाएगा या (ओं)।

  • दूसरी गोली एक वाक्यात्मक नियम है - नाम सिर्फ मेल खाना चाहिए - उनके अर्थ अप्रासंगिक अन्यथा है - वहाँ हो सकता था एक सदस्य इस तरह के निम्नलिखित के रूप में, X को प्रदान की गई टेम्पलेट तर्क में Base कहा जाता है, लेकिन का उपयोग कर घोषणा अभी भी कंस्ट्रक्टर्स आयात और नहीं नाम सदस्य Base करना होगा:

    template<typename T> struct D { private: T Base; }; 
    X<D> x; // valid, the private member is *not* touched! 
    
7

हाँ, ऐसा लगता है कि यह मानक से करता है, (फरवरी 2011 ड्राफ्ट), खंड 12.9:

template< class T > 
struct D : T { 
using T::T; // declares all constructors from class T 
~D() { std::clog << "Destroying wrapper" << std::endl; } 
}; 

कक्षा टेम्पलेट डी किसी भी वर्ग और आगे इसके निर्माताओं की सभी लपेटता, कोई संदेश लिख जब भी कक्षा डी का ऑब्जेक्ट नष्ट हो जाता है तो मानक लॉग में। अंत उदाहरण

एक और बात ध्यान देने योग्य है, जबकि मानक यह अनुमति देता है, this list के अनुसार, केवल 1 संकलक, आईबीएम XLC++, एक रिलीज़ संस्करण में इस सुविधा का समर्थन करता है। जीसीसी केवल वर्तमान में इसे पैच के साथ समर्थन करता है।

संपादित करें: AJG85 ने इंगित किया कि टेम्पलेट में टी हमेशा प्लेसहोल्डर को संदर्भित करता है, इसलिए 'टी :: टी' का उपयोग हमेशा टेम्पलेट तर्क को संदर्भित करता है।

+1

नहीं है कि ठीक होगा क्योंकि 'typename T' एक विधि नामित टी यह प्रकार प्रतीक के लिए एक प्लेसहोल्डर का प्रतिनिधित्व करता है का प्रतिनिधित्व नहीं करता के द्वारा उपयोग टेम्पलेट का तात्कालिकता। उदाहरण के लिए 'ए ' का परिणाम 'int :: int;' का उपयोग करेगा ... चेतावनी का शब्द: एक प्रकार के साथ क्या होता है जिसका मतलब एसटीएल कंटेनर जैसी बेस क्लास नहीं है? – AJG85

+0

आप सदस्य चर प्रश्न पर सही हैं। एक एसटीएल कंटेनर की विरासत के लिए, यह काम करेगा, लेकिन यदि आप पॉलिमॉर्फिक फैशन में प्रकार का उपयोग करना चाहते हैं तो आपको जोखिम हो रहा है। लेकिन अगर आप बस डी > बना रहे हैं, और उसके बाद इसे एक ही स्थान पर उपयोग कर रहे हैं, तो यह काम करेगा। यह अच्छा अभ्यास नहीं है, लेकिन यह काम करेगा। –

+0

सही लेकिन यह निश्चित रूप से कुछ ध्यान में रखना है क्योंकि व्युत्पन्न वस्तु में राज्य जोड़ना या बेस क्लास पॉइंटर्स का उपयोग करना गलती से टेम्पलेट के रूप में पेश किया जा सकता है, बाद में समस्या के बाद विरासत और मूल कारण को खराब कर देता है। – AJG85

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