在没有模板参数的派生类中使用模板类名称是否合法?

Con*_*tor 4 c++ inheritance templates language-lawyer c++17

以下代码使用clang ++ 8.0.0g ++ 9.1.0均可正常编译(编译标记为-Wall -Wextra -Werror -pedantic-errors):

template <typename>
struct Base
{
};

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

int main()
{
}
Run Code Online (Sandbox Code Playgroud)

是这些编译器中的错误还是C ++标准的功能?

Jar*_*d42 9

具有注入的类名

在内部Base<T>Base指(在某些情况下)Base<T>

Derived 然后也将使用该注入的类名。


Rad*_*ski 8

这段代码很好。内部DerivedBase将引用Base<int>因为 Derived继承自Base<int>。是的,这是合法的。

标准:

14.6.1.1:像普通的(非模板)类一样,类模板也具有注入的类名(第9条)。注入的类名称可以用作模板名称或类型名称。当它与template-argument-list一起使用,作为模板template-parameter的模板参数或作为朋友类模板声明的elaborated-type-specifier中的最终标识符时,它指的是类模板本身。否则,它等效于模板名称,后跟<>中包含的类模板的模板参数。

也:

3.4.3:出于名称隐藏和查找的目的,一个类的注入的类名(第9条)也被认为是该类的成员。

最后一句话做到了。简而言之,A<B>引入隐藏的“别名”,A = A<B>但前提A是不使用<>。在一个示例中,它是在基类中引入的,派生类继承了基类的所有成员。

  • 我还要添加[\ [basic.lookup \] / 3](http://eel.is/c++draft/basic.lookup#3),这意味着注入的类名像其他公共成员一样是继承的。 (3认同)