Why is using base class definitions in non-deduced context not permitted, and how to get around this?

c++, struct, templates

Solution

Because `type` is in a "dependent scope" you can access it like this:

typename Base<T>::Type

Your `Alias` should then be defined like this:

using Alias = typename Base<T>::Type;

Note that the compiler doesn't, at this point, know if `Base<T>::type` describes a member variable or a nested type, that is why the keyword `typename` is required.

Layers

You do not need to repeat the definition at every layer, here is an example, link:

template <typename T>
struct intermediate : Base<T>
{
    // using Type = typename Base<T>::Type; // Not needed
};

template <typename T>
struct Derived : intermediate<T>
{
    using Type = typename intermediate<T>::Type;
};

Update

You could also use the class it self, this relies on using an unknown specializations.

template <typename T>
struct Derived : Base<T>
{
    using Type = typename Derived::Type; // <T> not required here.
};

Problem

I have the following code: ``` #include <iostream> template <typename T> struct Base { using Type = int; }; template <typename T> struct Derived : Base<T> { //uncommmenting the below cause compiler error //using Alias = Type; }; int main() { Derived<void>::Type b = 1; std::cout << b << std::endl; return 0; } ``` Now the typename `Type` is available to `Derived` if its in a deduced context - as shown by the perfectly valid declaration of `b`. However, if I try to refer to `Type` inside the declaration of `Derived` itself, then I get a compiler error telling me that `Type` does not name a type (for example if the definition of `Alias` is uncommented). I guess this is something to do with the compiler not being able to check whether or not `Type` can be pulled in from the base class when it is parsing the definition of `Derived` outside the context of a specific instantiation of parameter `T`. In this case, this is frustrating, as `Base` always defines `Type` irrespective of `T`. So my question is twofold: 1). Why on Earth does this happen? By this I mean why does the compiler bother parsing `Derived` at all outside of an instantiation context (I guess non-deduced context), when not doing so would avoid these 'bogus' compiler errors? Perhaps there is a good reason for this. What is the rule in the standard that states this must happen? 2). What is a good workaround for precisely this type of problem? I have a real-life case where I need to use base class types in the definition of a derived class, but am prevented from doing so by this problem. I guess I'm looking for some kind of 'hide behind non-deduced context' solution, where I prevent this compiler 'first-pass' by putting required definitions/typedefs behind templated classes or something along those lines. EDIT: As some answers below point out, I can use `using Alias = typename Base<T>::Type`. I should have said from the outset, I'm aware this works. However, its not entirely satisfactory for two reasons: 1) It doesn't use the inheritance hierarchy at all (`Derived` would not have to be derived from `Base` for this to work), and I'm precisely trying to use types defined in my base class hierarchy and 2) The real-life case actually has several layers of inheritance. If I wanted to pull in something from several layers up this becomes really quite ugly (I either need to refer to a non-direct ancestor, or else repeat the `using` at every layer until I reach the one I need it at)

Original source

Related problems