base class using a type defined by the parent class
I have a Visual Studio 2008 C++ application where a base class A_Base
needs to instantiate a data member whose type is defined by a parent class. For example:
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;
}
Unfortunately, it appears the compiler doesn't know what T::Foo
is until it's too late and I get errors like this:
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
Is there any way to achieve this type of functionality?
Thanks, PaulH
A_Base<A>
is instantiated at a point where A
is not complete yet :
class A : public A_Base< A >
You could consider using a traits class :
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;
}
You can try the following:
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;
}
Class A
depends on class A_Base
which depends on class A
... etc. You have a recursion here. You need to declare Foo
in a separate class.
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 >
{
};
See also GotW #79.
精彩评论