2015-03-12 5 views
6

मैं एक प्रकार के Test को एक टेम्पलेट प्रकार Base से प्राप्त करना चाहता हूं जिसे मैं व्युत्पन्न प्रकार (यानी Base<Test>) पर विशेषज्ञ हूं।टेम्पलेट में नेस्टेड टाइपपीफ का उपयोग कैसे करें?

टेम्पलेट प्रकार के अंदर, मैं व्युत्पन्न प्रकार (टेम्पलेट पैरामीटर) में परिभाषित टाइपिफ़ का उपयोग करना चाहता हूं।

template <typename T> 
class Base 
{ 
protected: 
    void func(typename T::X x) {} 
}; 


class Test : public Base<Test> 
{ 
public: 
    typedef int X; 
}; 

यह संभव है, और यदि हां, ठीक मैं बनाने की जरूरत क्या है:

error C2039: 'X' : is not a member of 'Test' 

यहाँ कोड का टुकड़ा है:

हालांकि, मैं इस संकलन त्रुटि मिलती है?

(मैं इस तरह की समस्या के लिए जवाब के एक जोड़े को देखने, लेकिन मेरी परिदृश्य की तरह typename लगाकर द्वारा तय नहीं किया गया है ऐसा लगता है - यह व्युत्पन्न प्रकार के साथ विशेष किसी टेम्पलेट से पाने के साथ कुछ है?)

उत्तर

1

यह मेरे लिए काम करता है:

template <typename T> struct Traits; 

template <typename Derived> 
class Base 
{ 
    protected: 
     void func(typename Traits<Derived>::X x) {} 
}; 


class Test; 

template <> struct Traits<Test> 
{ 
    typedef int X; 
}; 


class Test : public Base<Test> 
{ 
}; 
+0

मुझे लगता है कि आपको इस तरह की चीज करने की इच्छा है - मुझे लगता है कि यह दो प्रकार के बीच परिपत्र संदर्भ से बचने के लिए एक इंटरफ़ेस निकालने जैसा है। – mackenir

+0

@ मैकनेर, यह देखने के लिए एक अच्छा तरीका है। –

1

मुझे इस व्यवहार के बारे में निश्चित नहीं है, शायद कोई इसे स्पष्ट कर सकता है। लेकिन जैसा कि मैं इस पल द्वारा : public Base<Test> करता हूं, टाइप नाम एक्स मौजूद नहीं है (क्योंकि नीचे घोषित किया गया है)।

यदि आप विरासत बनाने से पहले एक रैपर वर्ग बनाते हैं तो आप विरासत करते समय इस प्रकार मौजूद होंगे और टेम्पलेट इंस्टेंटेशन काम करेगा।

यह कुलपति ++ 2013

template <typename T> 
class Base 
{ 
protected: 
    void func(typename T::X x) {} 
}; 


class TestWrapper 
{ 
public: 
    typedef int X; //Declared, now it exists for the compiler 
}; 

class Test 
    :public Base<TestWrapper> //Compiles correctly 
{ 

}; 
2

साथ संकलित आप एक घेरा जो आगे घोषणाओं के साथ हल नहीं किया जा सकता है। लेकिन यह काम करेगा, हालांकि (मुझे संदेह है) जैसा कि आप चाहते थे काफी दृढ़ता से परिभाषित नहीं किया गया।

template <typename T> 
class Base 
{ 
protected: 
    template<typename Y> 
    void func(Y x) {} 
}; 

class Test : public Base<Test> 
{ 
public: 
    typedef int X; 
}; 

तो func सार्वजनिक थे, तो आप तो लिख सकता है

Test t; 
Test::X x; 
t.func(x) 

जो मजे की बात है आवर्ती टेम्पलेट पैटर्न मैं के बारे में सोच के किसी भी उपयोग के लिए संतोषजनक है।

+0

यह ऊपर मेरी नमूना डेमो कोड के लिए काम करता है , लेकिन मुझे नहीं लगता कि यह अधिक जटिल वास्तविक कोड के लिए काम करेगा जो मैं संकलित करने की कोशिश कर रहा हूं :) – mackenir

5

typedef के लिए वैकल्पिक रूप से, आप भी आधार वर्ग में दूसरा टेम्पलेट तर्क के रूप में प्रकार की घोषणा कर सकते हैं:

template <typename T, typename X> 
class Base 
{ 
protected: 
    void func(X x) {} 
}; 


class Test : public Base<Test, int> 
{ 
public: 
// typedef int X; 
}; 
+0

मुझे यह पसंद है। इसके अलावा, और स्टैक ओवरफ़्लो में आपका स्वागत है। – Bathsheba

+0

यह मेरा वर्तमान कामकाज है। – mackenir

+0

हालांकि यह शुद्ध सीआरटीपी नहीं है। – Bathsheba

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