2009-09-01 36 views
5

क्या किसी को पता है कि यह संकलित क्यों नहीं होगा? मैंने वीएस 2008 और जीसीसी दोनों की कोशिश की है 4. कुछ और दोनों त्रुटियों को थूकते हैं। इससे कोई फर्क नहीं पड़ता कि मैं "ThisFunctionDoesNotCompile()" का संदर्भ दे रहा हूं या नहीं।यह सी ++ टेम्पलेट कोड संकलित क्यों नहीं करता है?

मैं बेस पर दूसरे टेम्पलेट पैरामीटर के रूप में 'इंटरनल टाइप' को पास करके इसे काम कर सकता हूं, लेकिन मैं अभी भी उत्सुक हूं कि यह एक त्रुटि के रूप में क्यों आता है।

#include <iostream> 
using namespace std; 

class DataClass 
{ 
public: 
    int m_data; 
}; 

template<typename DerivedType> 
class Base 
{ 
public: 
    int ThisFunctionCompiles() 
    { 
     // No problems here. 

     typename DerivedType::InternalType temp; 
     temp.m_data = 5; 
     return temp.m_data; 
    } 

    // error C2039: 'InternalType' : is not a member of 'Derived<InInternalType>' 
    typename DerivedType::InternalType ThisFunctionDoesNotCompile() 
    { 
     return static_cast<DerivedType*>(this)->GetInternalData(); 
    } 
}; 

template<typename InInternalType> 
class Derived : public Base<Derived<InInternalType> > 
{ 
public: 
    typedef InInternalType InternalType; 

    InternalType GetInternalData() 
    { 
     return m_internalData; 
    } 

private: 
    InternalType m_internalData; 


public: 
    void SetInternalData(int newVal) 
    { 
     m_internalData.m_data = newVal; 
    } 
}; 

int main() 
{ 

    Derived<DataClass> testDerived; 
    testDerived.SetInternalData(3); 

    cout << testDerived.GetInternalData().m_data << endl; 
    cout << testDerived.ThisFunctionCompiles() << endl; 

    // The compiler gives an error regardless of whether or not this is commented out. 
    //cout << testDerived.ThisFunctionDoesNotCompile().m_data << endl; 

    return 0; 
} 

इन त्रुटियों को मैं वी.एस. 2008 में प्राप्त कर रहे हैं:

1>e:\test\generaltestprogram\generaltestprogram\main.cpp(27) : error C2039: 'InternalType' : is not a member of 'Derived<InInternalType>' 
1>  with 
1>  [ 
1>   InInternalType=DataClass 
1>  ] 
1>  e:\test\generaltestprogram\generaltestprogram\main.cpp(35) : see reference to class template instantiation 'Base<DerivedType>' being compiled 
1>  with 
1>  [ 
1>   DerivedType=Derived<DataClass> 
1>  ] 
1>  e:\test\generaltestprogram\generaltestprogram\main.cpp(58) : see reference to class template instantiation 'Derived<InInternalType>' being compiled 
1>  with 
1>  [ 
1>   InInternalType=DataClass 
1>  ] 
1>e:\test\generaltestprogram\generaltestprogram\main.cpp(27) : error C2146: syntax error : missing ';' before identifier 'ThisFunctionDoesNotCompile' 
1>e:\test\generaltestprogram\generaltestprogram\main.cpp(27) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
1>e:\test\generaltestprogram\generaltestprogram\main.cpp(28) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
1>e:\test\generaltestprogram\generaltestprogram\main.cpp(28) : warning C4183: 'ThisFunctionDoesNotCompile': missing return type; assumed to be a member function returning 'int' 

और ये क्या जीसीसी मुझे देता हैं:

main.cpp: In instantiation of 'Base<Derived<DataClass> >': 
main.cpp:96: instantiated from 'Derived<DataClass>' 
main.cpp:119: instantiated from here 
main.cpp:88: error: no type named 'InternalType' in 'class Derived<DataClass>' 

उत्तर

11

समय है कि टेम्प्लेटेड वर्ग बेस के रूप में instantiated है पर व्युत्पन्न वर्ग के माता-पिता, व्युत्पन्न वर्ग एक पूर्ण प्रकार नहीं है।

Base<Derived<DataClass> >Derived<DataClass> का मूल वर्ग है, इसे तत्काल Derived<DataClass> से तुरंत चालू किया जाना चाहिए। तो जब वर्ग Base<Derived<DataClass> > टेम्पलेट से बनाया गया है, Derived<DataClass> व्यवहार करता है जैसे कि यह एक आगे की घोषणा थी। और जैसा कि आप शायद जानते हैं, आप अधूरे प्रकार के सदस्यों का संदर्भ नहीं दे सकते हैं, न ही आपके आगे घोषित प्रकार घोषित कर सकते हैं, इसलिए आप यहां भाग्य से बाहर हैं।

यह, वैसे, यही कारण है कि टेम्पलेट का उपयोग कर एक उचित covariant क्लोन() विधि को कार्यान्वित करना मुश्किल है। here और here (मेरा) देखें।

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