为什么我不需要指定"typename"?在C ++ 20中的依赖类型之前? [英] 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
关键字.为什么会编译?
This bit of code compiled in C++20 (using gcc 10.1) without using the typename
keyword before the dependent type std::vector<T>::iterator
. Why does it compile?
#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>;
}
推荐答案
One of the new features in C++20 is Down with typename
.
在C ++ 17中,您必须在几乎所有与† 相关的上下文中提供typename
关键字,以从值中消除类型的歧义.但是在C ++ 20中,此规则放松了很多.在需要具有类型的所有情况下,typename
关键字不再是必需的.
In C++17, you had to provide the typename
keyword in nearly all† dependent contexts to disambiguate a type from a value. But in C++20, this rule is relaxed a lot. In all contexts where you need to have a type, the typename
keyword is no longer mandatory.
一个这样的上下文就是类范围内的函数的返回类型,如您的示例所示.其他包括成员声明中的类型,using声明右侧的类型,lambda的参数声明,要传递给static_cast
的类型,等等.有关完整列表,请参见本文.
One such context is the return type of a function in class scope, as in your example. Others include the type in a member declaration, the type on the right-hand side of a using declaration, the parameter declaration of a lambda, the type you're passing to static_cast
, etc. See the paper for the full list.
† 几乎所有原因都是因为总是排除了base-specifier和mem-initializer-id,例如:
† Nearly all because base-specifiers and mem-initializer-ids were always excluded, as in:
template <typename T> struct X : T::type { }; // always ok
这没关系,因为需要是一种类型.本文只是将这种逻辑(好,它必须是类型,所以我们假设它是一种类型)扩展到更多必须是类型的地方.
This is okay because, well, that needs to be a type. The paper simply extends this logic (well, it has to be a type, so let's just assume it's a type) to a lot more places that have to be types.
这篇关于为什么我不需要指定"typename"?在C ++ 20中的依赖类型之前?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!