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?
With injected-class-name
Inside Base<T>
, Base
refers (in some conditions) to Base<T>
.
Derived
would then uses that injected-class-name too.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With