2010-12-06 10 views
3

Ich habe eine Visual Studio 2008 C++ - Anwendung, in der eine Basisklasse A_Base ein Datenelement instanziieren muss, dessen Typ durch eine Elternklasse definiert ist. Zum Beispiel:Basisklasse mit einem durch die Elternklasse definierten Typ

template< typename T > 
class A_Base 
{ 
public: 
    typedef typename T::Foo Bar; // line 10 

private: 
    Bar bar_; 
}; 

class A : public A_Base<A> 
{ 
public: 
    typedef int Foo; 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    A a; 
return 0; 
} 

Leider scheint es der Compiler nicht weiß, was T::Foo ist, bis es zu spät ist und ich bekomme Fehler wie folgt aus:

1>MyApp.cpp(10) : error C2039: 'Foo' : is not a member of 'A' 
1>  MyApp.cpp(13) : see declaration of 'A' 
1>  MyApp.cpp(14) : see reference to class template instantiation 'A_Base<T>' being compiled 
1>  with 
1>  [ 
1>   T=A 
1>  ] 
1>MyApp.cpp(10) : error C2146: syntax error : missing ';' before identifier 'Bar' 
1>MyApp.cpp(10) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
1>MyApp.cpp(10) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 

Gibt es eine Möglichkeit, diese Art von zu erreichen Funktionalität?

Danke, PaulH

Antwort

3

Sie folgendes versuchen:

template< typename T > 
class A_Base 
{ 
public: 
    typedef typename T::Foo Bar; // line 10 

private: 
    Bar bar_; 
}; 

class A_Policy 
{ 
public: 
    typedef int Foo; 
}; 

class A : public A_Base<A_Policy> 
{}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    A a; 
return 0; 
} 
5

A_Base<A> an einem Punkt instanziiert wird, wo A noch nicht abgeschlossen ist:

class A : public A_Base<A> 

Sie betrachten eine Verwendung könnte Merkmalsklasse:

template<class T> struct traits; 

template< typename T > 
class A_Base 
{ 
public: 
    typedef typename traits<T>::Foo Bar; // line 10 

private: 
    Bar bar_; 
}; 

class A; // Forward declare A 

template<> // Specialize traits class for A 
struct traits<A> 
{ 
    typedef int Foo; 
}; 

class A : public A_Base<A> {}; 

int main() 
{ 
    A a; 
} 
1

Die Klasse A hängt von der Klasse A_Base ab, die von der Klasse A abhängt ... usw. Sie haben hier eine Rekursion. Sie müssen Foo in einer separaten Klasse deklarieren.

class A; 

template<typename T> struct Foo; 
template<> struct Foo<A> { typedef int type; }; 

template< typename T > 
class A_Base 
{ 
public: 
    typedef typename Foo<T>::type Bar; // line 10 

private: 
    Bar bar_; 
}; 

class A : public A_Base<A> 
{ 
}; 

Siehe auch GotW #79.