Home > Software engineering >  Why are public aliases not being inherited in this template class?
Why are public aliases not being inherited in this template class?

Time:12-12

#include <string>

template <class StringType>
class mytype
{
    struct mybase
    {
        using Type = StringType;
    };

    class mychild : public mybase
    {
        typename Type somevalue;
    };
};

int main()
{
    mytype<std::string> mt;
}

It produces this error:

error C3646: 'somevalue': unknown override specifier

message : see reference to class template instantiation 'mytype::mychild' being compiled

message : see reference to class template instantiation 'mytype' being compiled

error C4430: missing type specifier - int assumed. Note: C does not support default-int

Why is this not allowed?

CodePudding user response:

mybase is a dependent base class, because you could add arbitrary specializations of mytype<T>::mybase for some type T, so that it has different members.

Therefore the compiler cannot know at the point of definition of mychild that Type is a member of the base class. You could specialize it later to not have a Type member for some specializations. But the compiler needs to know whether Type is a type or not to parse the declaration. Names are not looked in dependent base classes for this reason.

You need to tell the compiler that you are sure that Type is a member of the base class and that it is a type, not something else:

class mychild : public mybase
{
    typename mybase::Type somevalue;
};

The typename here indicates to the compiler that the nested Type is really a type, since it can't look this up in the dependent base class at the point of definition for the reasons stated above.

If you then do specialize mytype<T>::mybase in such a way that it doesn't contain Type or Type is not a type, then instantiation of the corresponding mytype<T>::myclass will fail.

typename only makes sense before a nested name. If the name is not nested, then either it is not dependent and so can simply be looked up immediately (as the case in your example) or it is a member of the current instantiation, in which case the compiler also can be sure whether it is a type or not with a lookup in the template definition. typename before an unqualified name is a syntax error. (Aside from its other meaning in a template parameter.)

  • Related