Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it legal to use template class name in derived class without template arguments?

The following code compiles fine both with clang++ 8.0.0 and g++ 9.1.0 (compilation flags are -Wall -Wextra -Werror -pedantic-errors):

template <typename>
struct Base
{
};

struct Derived : Base<int>
{
    Base base()
    {
        return Base();
    }
};

int main()
{
}

Is it a bug in these compilers or a feature of the C++ standard?

like image 644
Constructor Avatar asked Dec 02 '22 10:12

Constructor


2 Answers

With injected-class-name

Inside Base<T>, Base refers (in some conditions) to Base<T>.

Derived would then uses that injected-class-name too.

like image 181
Jarod42 Avatar answered Dec 22 '22 05:12

Jarod42


This code is fine. Inside Derived class Base will refer to Base<int>, because Derived inherits from Base<int>. Yes, it's legal.

Standard:

14.6.1.1: Like normal (non-template) classes, class templates have an injected-class-name (Clause 9). The injected-class-name can be used as a template-name or a type-name. When it is used with a template-argument-list, as a template-argument for a template template-parameter, or as the final identifier in the elaborated-type-specifier of a friend class template declaration, it refers to the class template itself. Otherwise, it is equivalent to the template-name followed by the template-parameters of the class template enclosed in <>.

Also:

3.4.3: The injected-class-name of a class (Clause 9) is also considered to be a member of that class for the purposesof name hiding and lookup.

The last sentence does it. In short A<B> introduces hidden "alias" A = A<B> but only if A is used without <>. In an example it's introduced in base class and derived class inherits all members of base class.

like image 20
Radosław Cybulski Avatar answered Dec 22 '22 05:12

Radosław Cybulski