C++ 为什么不是';嵌套类型的基类是否需要t`typename`?

C++ 为什么不是';嵌套类型的基类是否需要t`typename`?,c++,templates,inheritance,C++,Templates,Inheritance,我非常惊讶地看到,当依赖类型显示为基类时,没有必要添加typename: struct B {}; struct wr { typedef B type; }; template<class T> struct A : T::type {}; int main() { A<wr> a; (void)a; } 结构B{}; 结构体 {typedef B type;}; 模板 结构A:T::类型 {}; int main() { A A; (a)无效;

我非常惊讶地看到,当依赖类型显示为基类时,没有必要添加
typename

struct B {};

struct wr
{ typedef B type; };

template<class T>
struct A : T::type
{};

int main()
{
    A<wr> a;
    (void)a;
}
结构B{}; 结构体 {typedef B type;}; 模板 结构A:T::类型 {}; int main() { A A; (a)无效; } 为什么在
t::type
前面不需要
typename

为什么在
t::type
前面不需要
typename

因为不能从值继承。您可以使用
typename
告诉编译器给定的嵌套标识符是一种类型,但对于继承,无论如何都必须是这种情况,这样您就可以忽略它-这就是为什么该语言为基本说明符提供了
typename
-规则的例外。来自(我的):

从属名称的
typename
消歧器

在模板(包括alias template)的声明或定义中,如果名称不是当前实例化的成员且依赖于模板参数,则该名称不被视为类型,除非使用关键字typename,或者,除非该名称已被确定为类型名,例如,使用typedef声明或命名基类


注意,我们将得到更多可以省略
typename
的地方,请参见。

如果您需要告诉编译器期望某个类型而不是其他类型,则只需使用
typename


因为只有一个类型可以从中继承,所以没有歧义,因此
typename
是多余的。

正如其他人所指出的,这是一个特例。要引用此标准,请执行以下操作:

[temp.res]

用作类或decltype或 详细类型说明符隐式假定为命名类型, 不使用typename关键字。在嵌套的名称说明符中 立即包含依赖于 模板参数,标识符或简单模板id是隐式的 假定为类型命名,不使用typename关键字。 [ 注意:typename关键字是不允许使用的语法 构造。 — 尾注 ]


在C++20中,除了需要
typename

之外,还会有更多的例外情况?@0x499602D2-函数返回类型、各种*_cast运算符的类型参数和一些默认模板参数。提供了示例和确切的详细信息。