为什么嵌套类型的基类不需要"typename"?
Why isn't `typename` required for a base class that is a nested type?
我很惊讶地看到,当依赖类型显示为基类时,没有必要添加typename
:
struct B {};
struct wr
{ typedef B type; };
template<class T>
struct A : T::type
{};
int main()
{
A<wr> a;
(void)a;
}
为什么typename
不需要在T::type
面前?
为什么
T::type
前面不需要typename
?
因为不能从值继承。你使用typename
告诉编译器给定的嵌套标识符是一种类型,但对于继承,无论如何都必须如此,所以你可以省略它 - 这就是为什么该语言为基本说明符提供了typename
规则的例外。来自 cpp偏好(强调我的(:
从属名称的
typename
消除歧义器在模板的声明或定义(包括别名模板(中,不是当前实例化的成员且依赖于模板参数的名称不被视为类型,除非使用关键字 typename 或除非它已建立为类型名称,例如,使用 typedef 声明或用于命名基类。
请注意,我们将获得更多可以省略typename
的地方,请参阅 P0634。
正如其他人指出的那样,这是一个特例。引用这方面的标准:
[温度]
5 在类或 decltype 中用作名称的限定名,或 精心设计的类型说明符被隐式假定为命名类型, 不使用 typename 关键字。在嵌套名称说明符中 它立即包含一个嵌套名称说明符,该说明符依赖于 模板参数,标识符或简单模板 ID 是隐式的 假定命名类型,而不使用 typename 关键字。 [ 注意:这些语法不允许使用typename关键字 构建。 — 尾注 ]
到了 C++20 年,需要typename
会有更多的例外.
只有当你需要告诉编译器需要一种类型而不是其他东西时,你才需要使用typename
。
由于只能从类型继承,因此没有歧义,因此typename
是多余的。
相关文章:
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有类似std::lower_bound的函数,而不需要排序/分区输入
- 为什么output_editor Concept不需要output_e迭代器标记
- 在除法中不需要四舍五入
- 与C代码相比,为什么C++代码不需要"#define _POSIX_C_SOURCE 200809L"?
- 将值从另一个数组写入数组,不包括不需要的值 C++
- C++ 写入路径名中包含不需要的空字符的文件
- 是否有必要获取锁并在不需要唤醒线程时通知condition_variable?
- 使用 assimp 加载模型 - 不需要提升?
- 为什么转换函数声明不需要至少一个定义类型说明符
- 返回不需要的值的二叉搜索程序
- 当我不需要数据库中的所有值时,如何部分初始化 c++ 对象?
- C++:用户输入会产生不需要的行为
- 如何在不需要LIBCD.lib的情况下在Visual Studio 6中编译C项目
- 为什么不需要在 C++20 中的依赖类型之前指定"typename"?
- 为什么在以下情况下不需要为依赖类型使用typename
- 为什么在VS2015中模板相关的嵌套类型名称中不需要typename关键字?
- 为什么嵌套类型的基类不需要"typename"?
- 在不需要时使用"template"和"typename"消除歧义器
- 为什么在Visual Studio 2008/2010中不需要typename __