I'm having trouble understanding why the code below doesn't compile -- could someone please explain?
How do I access a typedef in a derived class from the base class?
template<class Derived>
struct Test
{
template<class T>
typename Derived::value_type foo(T);
};
struct Derived : public Test<Derived>
{
typedef int value_type;
};
At the time of declaring Derived
, Derived
is not yet a complete type -- you've only just started declaring it! Hence in the specialization Test<Derived>
, the template argument is an incomplete type, and thus you mustn't refer to a nested name such as Derived::value_type
-- that's circular logic.
You could decycle the problem by making the return type a separate argument:
template <typename T, typename R> struct Test
{
template <typename U> R foo(U);
};
template <typename R>
struct BasicDerived : public Test<BasicDerived, R>
{
typedef R value_type;
};
typedef BasicDerived<int> Derived;
You can't access typedef
s or members of the template class directly in the base class, because at that point it's not a complete type. Allowing this would lead to circular behaviour:
template<class Derived>
struct Test
{
typedef typename Derived::value_type foo;
};
struct Derived : public Test<Derived>
{
typedef Test<Derived>::foo value_type;
};
You can however reference members of the template class within methods, as they are not instantiated until later:
template<class Derived>
struct Test
{
void foo() { typename Derived::value_type bar; }
};
struct Derived : public Test<Derived>
{
typedef int value_type;
};
Alternatively, depending on what you are trying for, you can pass the typedef as an additional template parameter:
template<typename value_type, class Derived>
struct Test
{
template<class T>
value_type foo(T);
};
struct Derived : public Test<int, Derived>
{
typedef int value_type;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With