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

时间:2019-06-21 12:57:41

标签: c++ templates inheritance 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()
{
}

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

2 个答案:

答案 0 :(得分:9)

使用injected-class-name

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

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

答案 1 :(得分: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<>一起使用时才使用。在示例中,它是在基类中引入的,派生类继承了基类的所有成员。