I have rather simple, I imagine, question about CRTP, but I cannot seem to find an answer to it. Probably, because it is so simple, no one thought of asking it. I am new to the concept, so, please don't laugh too hard ;).
Here is the code (it's sort of an attempt to do something similar to STL containers):
template< typename tT >
struct TBase
{
typedef tT T;
};
template< typename tTBase >
struct TTraitsBase
{
typedef typename tTBase::T T;
};
template< typename tTHelpee, typename tTTraits >
struct THelper
{
typedef typename tTTraits::T T;
typedef typename tTHelpee::T Th; /* This generates a compiler error:
'T' not being a member of TDerived<tT> */
T Foo( void )
{
return static_cast< tTHelpee* > ( this )->mVal;
}
};
template< typename tT >
struct TDerived : TBase< tT > , THelper< TDerived< tT > , TTraitsBase< TBase< tT > > >
{
using TBase< tT >::T;
T mVal;
};
int main()
{
TDerived< int >::T lTmp = -1;
TDerived< int > lObj;
lObj.mVal = -1;
std::cout << lObj.Foo() << std::endl;
return 0;
}
Everything compiles if I comment the offending typedef typename _THelpee::T Th;
. And that what confuses me: if compiler does not like typedef typename _THelpee::T Th;
, why does it let through static_cast< _THelpee* > ( this )->mVal
? I assume, it has something to do with not being able to instantiate THelper
when instantiating TDerived
, but no clear understanding. Can someone, please, give a brief explanation and/or some references on what is happening here? Thank you.
EDIT: removed '_T' prefix.