【发布时间】:2022-01-25 10:44:31
【问题描述】:
cpp 参考 (https://en.cppreference.com/w/cpp/concepts/totally_ordered) 说 std::totally_ordered<T> 仅在给定左值 a、b 和 c 类型为 const std::remove_reference_t<T> 的情况下建模:
-
bool(a < b)、bool(a > b)和bool(a == b)中的一个为真; - 如果
bool(a < b)和bool(b < c)都为真,那么bool(a < c)为真; bool(a > b) == bool(b < a)bool(a >= b) == !bool(a < b)bool(a <= b) == !bool(b < a)
于是我考虑了NaN,发现float不符合bool(a > b) == bool(b < a)这个句子。但是std::totally_ordered<float> 是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;
}
【问题讨论】:
-
仅供参考 创建 NaN 的标准方法 - en.cppreference.com/w/cpp/numeric/math/nan
-
这是一个语义要求,
static_assert是true并不代表它是建模的。 -
换句话说,该概念仅检查所有比较运算符是否有效。它无法检查他们是否创建了总订单。
标签: c++ language-lawyer c++20