I'm trying to use a type member of a class in its child, but I'm failing. In particular, I can't understand why this code does not compile:
template <typename T>
class A {
public:
using t = T;
A() {}
};
template <typename T>
class B: public A<T> {
public:
B() : A<T>() {}
A<T>::t foo(A<T>::t x) {
return x;
}
};
I've also tried A::t
and B::t
but none of them is working. Maybe I'm missing something on how to access inherited type members. Compiler Error:
error: need ‘typename’ before ‘A<T>::t’ because ‘A<T>’ is a dependent scope
A<T>::t foo(A<T>::t x) {
PS: I know that I could use simply T
instead of trying to access A::t
in this particular case, but the question is still valid.
Since A<T>::t
depends on a template parameter, it requires a typename
:
typename A<T>::t foo(typename A<T>::t x)
Because it depends on a template parameter, it must always be qualified (i.e. have ::
to the left of it), so just the plain t
wouldn't work.
typename B::t
would also work.
typename A::t
wouldn't work because injected-class-name A
itself (i.e. the shorthand version that doesn't require template arguments) also depends on a template parameter. You could do typename B::A::t
, but it's superfluous.
If you put this in your class: using typename A<T>::t;
Then you'll be able to use t
as is. Notably, using typename B::t;
doesn't work.
If the base class didn't depend on a template parameter (e.g. template <typename T> class B : public A<int>
), then typename
wouldn't be necessary.
In that case, all of the following would work: t
, B::t
, A::t
, B::A::t
, optionally with the template arguments for A
and/or B
specified.