"Inherited" types using CRTP and typedef
The following code does not compile. I get an error message: error C2039: 'Asub' : is not a member of 'C'
Can someone help me to understand this?
Tried VS2008 & 2010 compiler.
template <class T>
class B
{
typedef int Asub;
public:
void DoSomething(typename T::Asub it)
{
}
};
class C : public B<C>
{
public:
typedef int Asub;
};
class A
{
public:
typedef int Asub;
};
int _tmain(int argc, _TCHAR* argv[])
{
开发者_StackOverflow社区C theThing;
theThing.DoSomething(C::Asub());
return 0;
}
You are being a bit unfair to the compiler here - C
is incomplete without B<C>
fully known and when processing B<C>
, C
is still an incomplete type. There are similar threads on comp.lang.c++.moderated and comp.lang.c++.
Note that it works if you delay the use by moving it into a member function definition, e.g.:
struct C : B<C> {
void f() { typedef typename C::Asub Asub; }
};
You could work around the problem by either passing the types explicitly upward:
template<class T, class Asub> struct B { /* ... */ };
class C : B<C, int> { /* ... */ };
... or by moving them to some traits class if you need to pass more:
template<class T, class Traits> struct B {
void DoSomething(typename Traits::Asub it) {}
};
struct CTraits {
typedef int Asub;
};
struct C : B<C, CTraits> {
typedef CTraits::Asub Asub;
};
精彩评论