2
template <class Derived>
struct Base {
  typedef typename Derived::T T;
};

template <typename T_>
struct Impl : public Base<Impl<T_>> {
  typedef T_ T;
};

When initialized this, I got an error of

no type named 'T' in 'Impl'

So, how can I get typename defined in derived from base class?

melpomene
  • 84,125
  • 8
  • 85
  • 148
Sun Yi-Ming
  • 155
  • 2
  • 9
  • 1
    Possible duplicate of [Where and why do I have to put the "template" and "typename" keywords?](https://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords) – user0042 Dec 02 '17 at 10:08
  • It's not about the `typename' keyword itself, it's about typename visibility. – Sun Yi-Ming Dec 02 '17 at 10:11
  • I would say it's sort of circular definition, you are defining T twice in Impl, did you mean `struct Impl : public Base {`? – nsubiron Dec 02 '17 at 10:41
  • @nsubiron You can change the first typedef to `typedef typename Derived::T T2;`. Doesn't really affect the error. – melpomene Dec 02 '17 at 10:44
  • 1
    True, the problem is not the duplicate name. My guess then is that at the point the Base template is generated you don't know about the insides of Impl yet. The compiler needs first to generate the Base class in order to create Impl, so at that point Impl doesn't have a T type yet – nsubiron Dec 02 '17 at 10:55

1 Answers1

1

Find a way to do it, though it is not perfect but does work.

template <class T>
struct traits;

template <class Derived>
struct Base {
  typedef typename traits<Derived>::T T;
};

template <typename T_>
struct Impl : public Base<Impl<T_>> {
  typedef T_ T;
};

template <typename T_>
struct traits<Impl<T_>> {
  typedef T_ T;
};

It is not perfect because in the traits class, I cannot write

typedef typename Impl<T_>::T T;

It is still undefined.

Sun Yi-Ming
  • 155
  • 2
  • 9