为什么在 C++20 的这种情况下仍然需要 `typename` 前缀?

xml*_*lmx 2 c++ standards typename c++-concepts c++20

根据/sf/answers/4339380251/

C++20 的新特性之一是Down with typename

在 C++17 中,您必须在几乎所有†依赖上下文中提供 typename 关键字以消除类型与值的歧义。但是在 C++20 中,这个规则放宽了很多。在需要类型的所有上下文中, typename 关键字不再是必需的。

template<typename T>
concept IsOK = true;

template<typename T>
requires IsOK<T::U> // error: use ‘typename T::U’
void f()
{}

struct A
{
    using U = int;
};

int main()
{
    f<A>(); 
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,显然,IsOK概念只能接受类型。

为什么 typename 这里需要?

在线演示

Nic*_*las 10

答案是松散地谈论“上下文”的含义。什么功能正在做的是找到地方,它是语法上不可能超过一个类型名称以外的任何出现在那个位置。是那些typename不再需要的地方。

例如,using name = X;。从语法上讲,这是一个类型别名声明。因此,无论X是什么,语法都要求它是一种类型。如果X恰好是一个依赖于模板参数的名称,那么无论该名称是什么,都必须是一个类型。所以语法是明确的,typename是多余的。

语法name<X>声明它X是模板的模板参数name。但是模板参数不必是类型。一个特定的模板可以将一个类型作为一个特定的参数,但在语法上,它X可能是一个引用变量或模板的标识符。因此,您必须消除歧义的从属Xs。