2015-11-20 12 views
5

मान लीजिए इस प्रकार मैं एक टेम्पलेट T टेम्पलेट पैरामीटर P की एक नेस्टेड वर्ग का उपयोग करता है परिभाषित,:CRTP में टेम्पलेट पैरामीटर के नेस्टेड वर्ग का उपयोग करना

template<class P> class T 
{ 
public: 
    T(P& p) : p(p) {} 
    P& p; 
    typename P::Nested& get_nested() { return p.nested; } 
}; 

अगर मैं एक वर्ग A कि एक नेस्टेड वर्ग नामित शामिल घोषित अब

class A 
{ 
public: 
    class Nested 
    { 
    public: 
     int i; 
    }; 
    Nested nested; 
}; 

void test2a() 
{ 
    A a; 
    a.nested.i = 1; 
    T<A> t_a(a); 
    t_a.get_nested().i = 2; 
} 

, मैं एक वर्ग B कि, उसी तरह से, एक नेस्टेड CLA शामिल घोषित करने के लिए करना चाहते हैं: Nested, मुझे कोई समस्या नहीं के साथ प्रकार T<A> के एक चर परिभाषित कर सकते हैं एस एस Nested नामित और इस प्रकार है कि, T<B> से विरासत:

class B : public T<B> 
{ 
public: 
    class Nested 
    { 
    public: 
     int i; 
    }; 
    Nested nested; 
}; 

उपरोक्त कोड का संकलन त्रुटि के साथ विफल: "नेस्टेडबी का सदस्य नहीं है"

मुझे लगता है कि मैं समझता हूँ कि क्या हो रहा है: उस समय टेम्पलेट दर्ज किया गया है, कक्षा बी को विरासत के कारण अपूर्ण रूप से परिभाषित किया गया है।

हालांकि, मैं अगर वहाँ मदद के लिए ऐसा करने के लिए ...

धन्यवाद किसी भी तरह से है सोच रहा हूँ।

उत्तर

3

मैं अपने उदाहरण के लिए एक और दृष्टिकोण, बस

template<class P> class T 
{ 
public: 
    T(P& p) : p(p) {} 
    P& p; 
    auto& get_nested() { return p.nested; } 
}; 

साथ संकलन @ecatmur रूप में एक ही चाल का शोषण कर रहा था, लेकिन थोड़ा सरल:

template<class R = P> 
typename R::Nested& get_nested() { return p.nested; } 

इसी तरह, यहाँ संकलक है P::Nested के मूल्यांकन को स्थगित करने के लिए जब तक आप get_nested() पर कॉल न करें।

+0

एक तरह से यह करने के लिए वापसी प्रकार टेम्पलेट पैरामीटर पर निर्भर बनाने के लिए है Petr और ecatmur दोनों, इन चाल के लिए बहुत बहुत धन्यवाद। हालांकि, मैं एमएसवीसी 2010 कंपाइलर का उपयोग कर रहा हूं जो उनमें से किसी को संकलित नहीं करेगा। मैं गंभीरता से सी ++ 14 अनुपालन संकलक के उन्नयन के बारे में सोच रहा हूं ... अब। वैसे भी, आपके उत्तरों के लिए बहुत बहुत धन्यवाद। – shrike

+0

@SharpDressedMan, मेरे दूसरे समाधान के साथ सटीक समस्या और सटीक त्रुटि संदेश क्या है? ऐसा लगता है कि मेरे लिए सी ++ 03 भी है ... – Petr

+0

त्रुटि C4519 है: डिफ़ॉल्ट टेम्पलेट तर्क केवल क्लास टेम्पलेट पर ही अनुमति है। – shrike

6

आपको get_nested के रिटर्न प्रकार के रिज़ॉल्यूशन को तब तक स्थगित करने की आवश्यकता है जब तक इसे कॉल न किया जाए।

template<typename unused = void> 
    typename std::conditional<false, unused, P>::type::Nested& 
    get_nested() { return p.nested; } 

एक और तरीका है (के बाद से सी ++ 14) वापसी प्रकार कटौती का उपयोग करना है:

auto& get_nested() { return p.nested; } 
संबंधित मुद्दे

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