2009-09-01 6 views
5

왜 컴파일되지 않는지 아는 사람 있습니까? 나는 VS 2008과 GCC 4.something을 모두 시험해 보았고 두 가지 오류가 나왔다. "ThisFunctionDoesNotCompile()"을 참조하는지 여부는 중요하지 않습니다.왜이 C++ 템플릿 코드가 컴파일되지 않습니까?

두 번째 템플릿 매개 변수로 'InternalType'을 Base에 전달하여이 문제를 해결할 수 있지만 여전히 오류로 표시되는 이유는 여전히 궁금합니다.

#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; 
} 

이 내가 VS 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' 

그리고 이러한 GCC 내게주는 것 같습니다 템플릿 클래스 자료는 다음과 같이 인스턴스화되는 시점에서

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

에게 파생 된 클래스의 상위 클래스 인 파생 클래스는 완전한 유형이 아닙니다.

Base<Derived<DataClass> >Derived<DataClass>의 상위 클래스이므로 Derived<DataClass>을 인스턴스화하기 전에 인스턴스화해야합니다. 따라서 클래스 Base<Derived<DataClass> >이 템플릿에서 빌드 될 때 Derived<DataClass>은 앞으로 선언 인 것처럼 동작합니다. 그리고 여러분이 알고있는 것처럼, 불완전한 타입의 멤버를 참조 할 수 없으며, 네스트 타입을 선언 할 수 없으므로 여기서 벗어날 수 있습니다.

이 방법은 템플릿을 사용하여 적절하게 공변 (covariant) clone() 메소드를 구현하는 것이 어렵다. herehere (내)을 참조하십시오.

관련 문제