为什么在 C++20 中的这种情况下仍然需要 `typename` 前缀?
Why is `typename` prefix still required in such a case in C++20?
根据:
One of the new features in C++20 is Down with 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.
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>();
}
在上面的代码中,显然,IsOK
概念只能接受类型。
为什么这里需要typename
?
答案是笼统地谈论“上下文”的含义。 the feature 正在做的是找到 语法上不可能 除了类型名称之外的任何东西都出现在那个位置的地方。这是那些不再需要 typename
的地方。
例如,using name = X;
。从语法上讲,这是一个类型别名声明。因此,无论 X
是什么,语法 都要求 它是一种类型。如果 X
恰好是一个依赖于模板参数的名称,那么无论该名称是什么,都必须是一个类型。所以语法没有歧义,typename
是多余的。
语法 name<X>
声明 X
是模板 name
的模板参数。但是模板参数不必是类型。 specific 模板可以将类型作为特定参数,但 语法上、X
可能是引用变量或模板的标识符.因此,您必须消除歧义依赖 X
s.
根据
One of the new features in C++20 is Down with 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.
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>();
}
在上面的代码中,显然,IsOK
概念只能接受类型。
为什么这里需要typename
?
答案是笼统地谈论“上下文”的含义。 the feature 正在做的是找到 语法上不可能 除了类型名称之外的任何东西都出现在那个位置的地方。这是那些不再需要 typename
的地方。
例如,using name = X;
。从语法上讲,这是一个类型别名声明。因此,无论 X
是什么,语法 都要求 它是一种类型。如果 X
恰好是一个依赖于模板参数的名称,那么无论该名称是什么,都必须是一个类型。所以语法没有歧义,typename
是多余的。
语法 name<X>
声明 X
是模板 name
的模板参数。但是模板参数不必是类型。 specific 模板可以将类型作为特定参数,但 语法上、X
可能是引用变量或模板的标识符.因此,您必须消除歧义依赖 X
s.