【问题标题】:Why does std::totally_ordered<float> return true?为什么 std::totally_ordered<float> 返回 true?
【发布时间】:2022-01-25 10:44:31
【问题描述】:

cpp 参考 (https://en.cppreference.com/w/cpp/concepts/totally_ordered) 说 std::totally_ordered&lt;T&gt; 仅在给定左值 a、b 和 c 类型为 const std::remove_reference_t&lt;T&gt; 的情况下建模:

  • bool(a &lt; b)bool(a &gt; b)bool(a == b) 中的一个为真;
  • 如果bool(a &lt; b)bool(b &lt; c)都为真,那么bool(a &lt; c)为真;
  • bool(a &gt; b) == bool(b &lt; a)
  • bool(a &gt;= b) == !bool(a &lt; b)
  • bool(a &lt;= b) == !bool(b &lt; a)

于是我考虑了NaN,发现float不符合bool(a &gt; b) == bool(b &lt; a)这个句子。但是std::totally_ordered&lt;float&gt;true。 我是不是做错了什么?

=======

我用这个宏来创建NaN

#define NAN        ((float)(INFINITY * 0.0F))

这是我的代码:

#include <iostream>
#include <concepts>

using namespace std;

int main(int argc, char* argv[])
{
    /*
    1) std::totally_ordered<T> is modeled only if, given lvalues a, b and c of type const std::remove_reference_t<T>:
    Exactly one of bool(a < b), bool(a > b) and bool(a == b) is true;
    If bool(a < b) and bool(b < c) are both true, then bool(a < c) is true;
    bool(a > b) == bool(b < a)
    bool(a >= b) == !bool(a < b)
    bool(a <= b) == !bool(b < a)
    */
    constexpr bool b = totally_ordered<float>; // true
    cout << typeid(NAN).name() << endl;        // float
    cout << NAN << endl;
    cout << b << endl;

    cout << "Exactly one of bool(a < b), bool(a > b) and bool(a == b) is true;" << endl;
    cout << (NAN < NAN) << endl;
    cout << (NAN > NAN) << endl;
    cout << (NAN == NAN) << endl;

    cout << " If bool(a < b) and bool(b < c) are both true, then bool(a < c) is true;" << endl;
    cout << (1.f < 2.f) << endl;
    cout << (2.f < NAN) << endl;
    cout << (1.f < NAN) << endl;

    cout << "bool(a > b) == bool(b < a)" << endl; ////// IT IS FALSE //////
    cout << (NAN > 1.f) << endl;
    cout << (1.f < NAN) << endl;

    cout << "bool(a >= b) == !bool(a < b)" << endl;
    cout << (NAN >= 1.f) << endl;
    cout << (NAN < 1.f) << endl;

    cout << "bool(a <= b) == !bool(b < a)" << endl;
    cout << (NAN <= 1.f) << endl;
    cout << (NAN > 1.f) << endl;
    cout << endl;
}

【问题讨论】:

标签: c++ language-lawyer c++20


【解决方案1】:

概念具有句法要求,即存在某些表达式集并且属于提供特定行为的类型。 C++20 的concept 特性可以检测到这些。

概念有语义要求,关于表达的意义的要求,可能是相对的。 concept 功能不能(通常)检测到这些。如果一个类型满足句法和语义要求,则可以说它“建模”了一个概念。

对于totally_orderedfloat 满足概念的句法要求,但 IEEE754 浮点数不满足语义要求。事实上,C++20 在符号中使用totally_ordered&lt;float&gt; 作为an example of this syntactic vs. semantic divide

一些concepts 试图通过要求用户明确选择加入语义要求来解决此问题。但totally_ordered 不是其中之一。

【讨论】:

    猜你喜欢
    • 2015-02-08
    • 2017-03-04
    • 1970-01-01
    • 2017-07-29
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    • 2010-09-13
    • 2017-05-03
    相关资源
    最近更新 更多