简体   繁体   English

在哪些情况下 std::optional operator == 会导致未定义的行为?

[英]In which cases does std::optional operator == cause undefined behavior?

Cppreference has the following description of mixed (optional and some other non-optional type) comparison operators for std::optional : Cppreferencestd::optional的混合(可选和一些其他非可选类型)比较运算符有以下描述:

Compares opt with a value.将 opt 与值进行比较。 The values are compared (using the corresponding operator of T) only if opt contains a value.只有当 opt 包含一个值时,才会比较这些值(使用 T 的相应运算符)。 Otherwise, opt is considered less than value.否则, opt 被认为小于值。 If the corresponding two-way comparison expression between *opt and value is not well-formed, or if its result is not convertible to bool, the behavior is undefined.如果 *opt 和 value 之间对应的双向比较表达式格式不正确,或者其结果不能转换为 bool,则行为未定义。

What confuses me here is:这里让我感到困惑的是:

  • What would be examples of these not well-formed comparisons?这些格式不正确的比较的例子是什么?

  • Why don't compilers/STL just reject the invalid comparisons instead of giving us UB?为什么编译器/STL 不拒绝无效的比较而不是给我们 UB?

This stems from imprecise specification, which has since been rectified.这源于不精确的规范,此后已得到纠正。

In C++17 , these comparisons were specified as:C++17中,这些比较被指定为:

Requires : The expression *x == *y shall be well-formed and its result shall be convertible to bool .要求:表达式*x == *y应格式正确,其结果应可转换为bool

Requires was a precondition, so failing to meet these conditions would be undefined behavior . Requires 是一个先决条件,因此不满足这些条件将是未定义的行为 But there are many different kinds of "preconditions" - does it mean check this statically, does this mean remove the operator from the overload set if the conditions aren't met, does it mean actual undefined behavior?但是有许多不同种类的“先决条件”——这是否意味着静态检查,这是否意味着如果条件不满足,则将运算符从重载集中删除,是否意味着实际的未定义行为?

In C++20 , these are instead specified as:C++20中,这些被指定为:

Mandates : The expression *x == *y is well-formed and its result is convertible to bool .要求:表达式*x == *y格式正确,其结果可转换为bool

Which means that the program is ill-formed if the conditions aren't met.意味着如果不满足条件,则程序格式错误。 Basically, a mandate is a static_assert (or equivalent).基本上,授权是一个static_assert (或等价物)。

So yes, the standard library is obligated to reject types whose comparison either doesn't exist or doesn't give you something like a bool .所以是的,标准库有义务拒绝比较不存在或不给你类似bool的类型。 This was never actually going to give you undefined behavior (what would an implementation do if it didn't have such an operator, read a bit from /dev/random ?) but now it's just much more clearly specified.这实际上永远不会给您未定义的行为(如果没有这样的运算符,实现会做什么,从/dev/random读取一点?)但现在它被更明确地指定了。


These changes came from a series of papers by Marshall Clow entitled "Mandating the Standard Library", this one specifically from P1460 (thanks, Marshall.).这些变化来自 Marshall Clow 题为“Mandating the Standard Library”的一系列论文,这篇论文特别来自P1460 (感谢 Marshall。)。 The new terminology for specifying the standard library comes from Walter Brown's "Guidelines for Formulating Library Semantics Specifications" paper ( P1369 ).用于指定标准库的新术语来自 Walter Brown 的“Guidelines for Formulating Library Semantics Specifications”论文 ( P1369 )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM