2010-02-18 15 views
7

निम्न पर विचार करें:हम subclass में एक templated घोंसला वर्ग टाइप या परिभाषित कैसे करते हैं?

template <typename T> 
class Base { 
    public: 
    template <typename U> 
    class Nested { }; 
}; 

template <typename T> 
class Derived : public Base<T> { 
    public: 
    //How do we typedef of redefine Base<T>::Nested? 
    using Base<T>::Nested; //This does not work 
    using Base<T>::template<typename U> Nested; //Cannot do this either 
    typedef typename Base<T>::template<typename U> Nested Nested; //Nope.. 

    //now we want to use the Nested class here 
    template <typename U> 
    Class NestedDerived : public Nested { }; 

    //or like this: 
    Nested<int> nestedVar; // obviously does not work 
}; 

व्युत्पन्न कक्षा में टेम्पलेटेड नेस्टेड क्लास का उपयोग कैसे करें? क्या यह सी ++ मानक के वर्तमान संस्करण में करना संभव है?

+0

मुझे समझ नहीं आता तुम क्यों कर रहे हैं एक 'व्युत्पन्न' वर्ग को नेस्टेड किया गया है, क्योंकि क्लास व्युत्पन्न वैसे भी नेस्टेड क्लास का वारिस करेगा। – Craig

+0

मैं "बेस" में encapsulated "Nested" कक्षा चाहता हूं, और "व्युत्पन्न" कक्षा "बेस :: नेस्टेड" कक्षा का विस्तार या उपयोग कर सकते हैं। – leiiv

+0

किस प्रयोग-मामले में 'बेस :: नेस्टेड का उपयोग करते हुए,' काम नहीं करते? –

उत्तर

10

असल using काम करता है के रूप में विज्ञापित है, यह सिर्फ टेम्पलेट में निर्भर नाम मुद्दे से छुटकारा पाने के नहीं है और यह नहीं वर्तमान में उर्फ ​​टेम्पलेट्स सीधे (fixed in C++0x हो जाएगा) कर सकते हैं:

template <class T> 
struct Base { 
    template <class U> struct Nested {}; 
}; 

template <class T> 
struct Derived : Base<T> { 
    using Base<T>::Nested; 

    // need to prefix Nested with template because 
    // it is a dependent template: 
    struct X : Base<T>::template Nested<int> {}; 

    // same here: 
    template<class U> 
    struct Y : Base<T>::template Nested<U> {}; 

    // data member, typename is needed here: 
    typename Base<T>::template Nested<int> data; 
}; 

void f() { 
    Derived<int>::Nested<int> n; // works fine outside 
} 

नहीं है एक और संभव पकड़ लिया जब टेम्पलेट्स में Derived<T>::Nested का उपयोग कर, लेकिन फिर से कि एक आश्रित नाम मुद्दा, नहीं विरासत से संबंधित है:

template<class T> 
void g() { 
    // Nested is a dependent type and a dependent template, thus 
    // we need 'typename' and 'template': 
    typedef typename Derived<T>::template Nested<int> NestedInt; 
} 

बस याद रखें कि ऐसे नाम हैं जो टेम्पलेट पर निर्भर तर्क

  • typename अगर इसकी एक आश्रित प्रकार के साथ उपसर्ग होना जरूरी: typename A<T>::B
  • सीधे template लगी होती है, तो इसकी एक आश्रित टेम्पलेट: A<T>::template f<int>()
  • दोनों दोनों यदि: typename A<T>::template B<int>
  • typename आधार स्तरीय सूचियों में गैर कानूनी है: template<class T> struct A : B<T>, C<T>::template D<int> {};
+0

क्या आप उदाहरण दे सकते हैं कि व्युत्पन्न वर्ग के डेटा सदस्य के लिए नेस्टेड प्रकार का उपयोग कैसे करें? अगर हमें अभी भी 'बेस ::' का उपयोग करना है, तो 'बेस :: नेस्टेड' का उपयोग बेकार हो जाएगा? – leiiv

+1

करेगा। 'बेस का उपयोग करके :: नेस्टेड' बेकार नहीं है, हालांकि इसका उपयोग 'f()' और 'g()' में किया जाता है - बिना 'उपयोग' घोषणा के, आपको 'बेस' के माध्यम से 'नेस्टेड' तक पहुंचना होगा। च() '। –

+0

धन्यवाद जीएफ, यह बहुत उपयोगी है। – leiiv

0

इस प्रयास करें:

template <typename T> 
class Base { 
    public: 
    template <typename U> 
    class Nested { }; 
}; 

template <typename T> 
class Derived : public Base<T> { 
    public: 
    //How do we typedef of redefine Base<T>::Nested? 
    //using Base<T>::Nested; //This does not work 
    //using Base<T>::template<typename U> Nested; //Cannot do this either 
    //typedef typename Base<T>::template<typename U> Nested Nested; //Nope.. 

    //now we want to use the Nested class here 
    template <typename U> 
    class NestedDerived : public Base<T>::template Nested<U> { }; 
}; 

int main() 
{ 
    Base<int>::Nested<double> nested; 

    Derived<int>::NestedDerived<double> nested_derived; 

    return 0; 
} 

स्लैकवेयर 13

+0

का उपयोग कर रहा हूं, लेकिन यह मैं नहीं पूछ रहा हूं। मैं क्या जानना चाहता हूं, क्या टाइप किया गया है या 'सार्वजनिक आधार :: टेम्प्लेट नेस्टेड ' 'व्युत्पन्न 'कक्षा के अंदर उपयोग करना संभव है, क्योंकि उस प्रकार का उपयोग कई स्थानों पर किया जाएगा। – leiiv

+0

ठीक है, क्षमा करें, मैं एक उपयुक्त उत्तर खोजने की कोशिश करूंगा – coelhudo

0

पर जीसीसी 4.3.3 का उपयोग कर ठीक संकलित मैं अभी भी नहीं 100% यकीन है कि आप क्या चाहते हैं, लेकिन आप की कोशिश कर सकते।
:
यह दृश्य स्टूडियो पर संकलित

template <typename T> 
class Base { 
    public: 
    template <typename U> 
    class Nested { }; 
}; 

template <typename T> 
class Derived : public Base<T> { 
    public: 
    //now we want to use the Nested class here 
    template <typename U> 
    class NestedDerived : public Nested<U> { }; 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
Base<int>::Nested<double> blah2; 
Derived<int>::NestedDerived<int> blah; 

return 0; 
} 
+0

यह \t व्युत्पन्न का उपयोग भी कर सकता है :: नेस्टेड blah3; – Craig

+0

आह अच्छा ओएल 'वीएस .. जी ++ 4.4.1 मुझे ऐसा करने नहीं देता .. – leiiv

+0

मैंने क्या किया और क्रेग ने क्या किया के बीच क्या अंतर है? मैंने वास्तव में नहीं देखा था:/ – coelhudo

2

यह काम करने के लिए लगता है (संपादित करें:।! पहले टेम्पलेट बयान को दिखाने के लिए कुछ और पंक्तियां जोड़ी और समीर तलवार के लिए धन्यवाद मेरी स्वरूपण को सही करने के लिए)

template <typename T, typename U> 
class Derived : public Base<T> { 
    public: 
    typedef typename Base<T>::template Nested<U> Nested; 

    class NestedDerived : public Nested { }; 

    Nested nestedVar; 
}; 
+0

लेकिन अब उपयोगकर्ताओं को हमेशा 'व्युत्पन्न' के लिए एक दूसरा टेम्पलेट तर्क निर्दिष्ट करना होगा। –

+0

हां, और एक व्युत्पन्न में एक से अधिक प्रकार के नेस्टेड डेरिवेट नहीं हो सकते हैं। यह एक गंभीर सीमा है, लेकिन अन्यथा मुझे NestedDerived बेस :: नेस्टेड का उपयोग करने का कोई तरीका नहीं दिखता है। – Beta

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