为什么我不需要在 C++20 中的依赖类型之前指定 "typename"?
Why don't I need to specify "typename" before a dependent type in C++20?
这段代码是用 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>;
}
C++20 的新特性之一是 Down with typename
。
在 C++17 中,您必须在几乎所有† 依赖上下文中提供 typename
关键字来消除歧义来自值的类型。但在 C++20 中,这条规则放宽了很多。在您 需要 类型的所有上下文中,typename
关键字不再是必需的。
一个这样的上下文是 class 范围内的函数的 return 类型,如您的示例所示。其他包括成员声明中的类型、using 声明右侧的类型、lambda 的参数声明、传递给 static_cast
的类型等。完整内容请参阅论文列表。
† 几乎都是因为基本说明符和 mem-initializer-ids 总是被排除在外,如:
template <typename T> struct X : T::type { }; // always ok
这没关系,因为 需要 是一种类型。该论文只是将此逻辑(好吧,它必须是一种类型,所以我们假设它是一种类型)扩展到更多必须是类型的地方。
从 reference 开始,从 c++20 开始,在从属名称明确为类型名称的上下文中,不再需要 typename
关键字。特别是:
A qualified name that is used as a declaration specifier in the (top-level) decl-specifier-seq of:
a simple declaration or function definition at namespace scope
这段代码是用 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>;
}
C++20 的新特性之一是 Down with typename
。
在 C++17 中,您必须在几乎所有† 依赖上下文中提供 typename
关键字来消除歧义来自值的类型。但在 C++20 中,这条规则放宽了很多。在您 需要 类型的所有上下文中,typename
关键字不再是必需的。
一个这样的上下文是 class 范围内的函数的 return 类型,如您的示例所示。其他包括成员声明中的类型、using 声明右侧的类型、lambda 的参数声明、传递给 static_cast
的类型等。完整内容请参阅论文列表。
† 几乎都是因为基本说明符和 mem-initializer-ids 总是被排除在外,如:
template <typename T> struct X : T::type { }; // always ok
这没关系,因为 需要 是一种类型。该论文只是将此逻辑(好吧,它必须是一种类型,所以我们假设它是一种类型)扩展到更多必须是类型的地方。
从 reference 开始,从 c++20 开始,在从属名称明确为类型名称的上下文中,不再需要 typename
关键字。特别是:
A qualified name that is used as a declaration specifier in the (top-level) decl-specifier-seq of:
a simple declaration or function definition at namespace scope