5

Let's start with the code example, because it should be easy to see what's going on:

template <typename T>
struct Base
{
    using Type = int;
};

template<typename T>
struct Derived : public Base<T>
{
    // error: unknown type name 'Type'
    using NewType = Type;
};

int main()
{}

I would have expected Derived to find Base's Type alias. However, none of the compilers I've tried (MSVC, Clang, GCC) seem to like this code.

More surprisingly, changing Derived's inheritance to:

struct Derived : public Base<int>

fixes the problem.

Is there something I can change to allow Derived to find Base's alias?

bolov
  • 72,283
  • 15
  • 145
  • 224
Joshua Maiche
  • 295
  • 2
  • 6

1 Answers1

6

because Type is a dependent name (it depends on the template Base<T>). You need to qualify it and use typename. You can also qualify it with Derived:: (as the op himself figure it out):

template<typename T>
struct Derived : public Base<T>
{
    using NewType = typename Base<T>::Type;
    // or
    using NewType2 = typename Derived::Type;
};

You can read more about dependent names here:

https://en.cppreference.com/w/cpp/language/dependent_name

How do you understand dependent names in C++

Where and why do I have to put the "template" and "typename" keywords?

Why do I have to access template base class members through the this pointer?

"not declared in this scope" error with templates and inheritance

bolov
  • 72,283
  • 15
  • 145
  • 224
  • Thanks for the answer; the lack of context makes sense for why it can't figure out Type--for all it knows; the base class will be specialized to have something completely different. Your solution relies on us knowing where Type comes from, though. Looking at your last link gave me the idea of using ```using NewType = typename Derived::Type;``` which makes things easier for multiple inheritance and the like. Would you mind adding that to your solution? It would have helped my situation a lot. – Joshua Maiche Aug 03 '19 at 20:23
  • @JoshuaMaiche exactly. Also yes, I agree `Derived::Type;` is better. Good catch – bolov Aug 03 '19 at 22:21