为什么 C++20 的 requires 表达式的行为不符合预期?
Why does C++20's requires expression not behave as expected?
#include <type_traits>
template<typename T>
struct IsComplete final
: std::bool_constant<requires{sizeof(T);}>
{};
int main()
{
struct A;
static_assert(!IsComplete<A>::value); // ok
struct A{};
static_assert(IsComplete<A>::value); // error
}
我预计第二个 static_assert
应该是正确的,因为 A 现在是一个完整的类型。
为什么 C++20 要求表达式的行为不符合预期?
这是一个错误的期望。首先,class 模板在翻译单元中只有一个实例化点:
[temp.point]
7 ... A specialization for a class template has at most one point of
instantiation within a translation unit. A specialization for any
template may have points of instantiation in multiple translation
units. If two different points of instantiation give a template
specialization different meanings according to the one-definition
rule, the program is ill-formed, no diagnostic required.
模板不允许程序中的两个点对同一组参数的模板有不同的解释(一般情况下是 ODR 噩梦)。你基本上开始冒险进入鼻恶魔领域,尝试这个特征。
如果您认为使用 C++20 概念会改变任何事情,您将直接进入病式;如果您将示例概念化,则无需诊断领域
template<typename T>
concept IsComplete = requires{sizeof(T);};
int main()
{
struct A;
static_assert(!IsComplete<A>); // ok
struct A{};
static_assert(IsComplete<A>); // error or nuclear launch.
}
[temp.names]
8 ... A concept-id evaluates to true if the concept's normalized
constraint-expression is satisfied ([temp.constr.constr]) by the
specified template arguments and false otherwise.
[temp.constr.atomic]
3 ... If, at different points in the program, the satisfaction
result is different for identical atomic constraints and template
arguments, the program is ill-formed, no diagnostic required.
这不是什么新东西,概念只是添加了更多相同的内容。如果某些 属性 参数在程序中的两个不同点不同,则模板对一组特定参数的含义不得更改。
因此,虽然检查类型是否完整的概念(即使在 C++20 之前的 SFINAE hackery 中)可能被编写,但不小心使用它就是玩弄火.
#include <type_traits>
template<typename T>
struct IsComplete final
: std::bool_constant<requires{sizeof(T);}>
{};
int main()
{
struct A;
static_assert(!IsComplete<A>::value); // ok
struct A{};
static_assert(IsComplete<A>::value); // error
}
我预计第二个 static_assert
应该是正确的,因为 A 现在是一个完整的类型。
为什么 C++20 要求表达式的行为不符合预期?
这是一个错误的期望。首先,class 模板在翻译单元中只有一个实例化点:
[temp.point]
7 ... A specialization for a class template has at most one point of instantiation within a translation unit. A specialization for any template may have points of instantiation in multiple translation units. If two different points of instantiation give a template specialization different meanings according to the one-definition rule, the program is ill-formed, no diagnostic required.
模板不允许程序中的两个点对同一组参数的模板有不同的解释(一般情况下是 ODR 噩梦)。你基本上开始冒险进入鼻恶魔领域,尝试这个特征。
如果您认为使用 C++20 概念会改变任何事情,您将直接进入病式;如果您将示例概念化,则无需诊断领域
template<typename T>
concept IsComplete = requires{sizeof(T);};
int main()
{
struct A;
static_assert(!IsComplete<A>); // ok
struct A{};
static_assert(IsComplete<A>); // error or nuclear launch.
}
[temp.names]
8 ... A concept-id evaluates to true if the concept's normalized constraint-expression is satisfied ([temp.constr.constr]) by the specified template arguments and false otherwise.
[temp.constr.atomic]
3 ... If, at different points in the program, the satisfaction result is different for identical atomic constraints and template arguments, the program is ill-formed, no diagnostic required.
这不是什么新东西,概念只是添加了更多相同的内容。如果某些 属性 参数在程序中的两个不同点不同,则模板对一组特定参数的含义不得更改。
因此,虽然检查类型是否完整的概念(即使在 C++20 之前的 SFINAE hackery 中)可能被编写,但不小心使用它就是玩弄火.