在 C + + 20中,为什么不需要在依赖类型之前指定“ typeename”?

这段代码是用 C + + 20(使用 gcc 10.1)编译的,没有在依赖类型 std::vector<T>::iterator之前使用 typename关键字。为什么要编译?

#include <vector>


template<typename T>
std::vector<T>::iterator // Why does this not require "typename" before it?
f() { return {}; }


int main() {
auto fptr = &f<int>;
}

代码游乐场

4301 次浏览

C + + 20中的一个新特性是 typename下降

在 C + + 17中,需要在几乎所有 & 匕首;相关上下文中提供 typename关键字,以消除类型与值之间的歧义。但是在 C + + 20中,这个规则放宽了很多。在 需要具有类型的所有上下文中,不再强制使用 typename关键字。

其中一个上下文是类范围中函数的返回类型,如您的示例所示。其他类型包括成员声明中的类型、 using 声明右边的类型、 lambda 的参数声明、要传递给 static_cast的类型等等。请看报纸上的完整清单。


几乎所有这些都是因为基本说明符和 mem 初始化符 id 总是被排除在外,例如:

template <typename T> struct X : T::type  { }; // always ok

这没关系,因为 需求是一个类型。本文只是简单地将这个逻辑(好吧,它必须是一个类型,所以让我们假设它是一个类型)扩展到更多必须是类型的地方。

参考文献到 c + + 20,在依赖名称明确为类型名称的上下文中,不再需要 typename关键字。特别是:

在(顶级) decl-specfier-seq 中用作声明说明符的限定名:

命名空间范围内的简单声明或函数定义