为什么 std::totally_ordered<float> return 是真的?
Why does std::totally_ordered<float> return true?
cpp 参考资料 (https://en.cppreference.com/w/cpp/concepts/totally_ordered) 说 std::totally_ordered<T>
仅在给定 const std::remove_reference_t<T>
类型的左值 a、b 和 c 时建模:
- 恰好
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;
}
概念有句法要求,存在一些表达式集并且是提供特定行为的类型。 C++20的concept
特性可以检测到这些。
概念也有语义要求,关于表达的意义的要求,可能是相对的。 concept
功能 不能 (通常)检测到这些。如果一种类型满足句法和语义要求,则称其为概念“建模”。
对于totally_ordered
,float
满足概念的句法要求,但是IEEE754浮点数不满足语义要求。实际上,C++20 在符号中使用 totally_ordered<float>
作为 an example of this syntactic vs. semantic divide。
一些 concept
试图通过要求用户明确选择加入语义要求来解决这个问题。但是 totally_ordered
不是其中之一。
cpp 参考资料 (https://en.cppreference.com/w/cpp/concepts/totally_ordered) 说 std::totally_ordered<T>
仅在给定 const std::remove_reference_t<T>
类型的左值 a、b 和 c 时建模:
- 恰好
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;
}
概念有句法要求,存在一些表达式集并且是提供特定行为的类型。 C++20的concept
特性可以检测到这些。
概念也有语义要求,关于表达的意义的要求,可能是相对的。 concept
功能 不能 (通常)检测到这些。如果一种类型满足句法和语义要求,则称其为概念“建模”。
对于totally_ordered
,float
满足概念的句法要求,但是IEEE754浮点数不满足语义要求。实际上,C++20 在符号中使用 totally_ordered<float>
作为 an example of this syntactic vs. semantic divide。
一些 concept
试图通过要求用户明确选择加入语义要求来解决这个问题。但是 totally_ordered
不是其中之一。