C++20 中进行了更改,我很难在标准中找到可以查看的位置以了解发生了此更改。有人可以引用一下标准中告诉我这会发生的部分吗?
我知道这个问题:Breaking change in std::tuple lexicographic comparison in C++20 with conversion operators?
但它没有回答我在标准中哪里可以找到这个问题。
使用 gcc 11.2 和 clang,此代码使用 -std=c++17
和 10
打印出 01
(预期结果)与-std=c++20
。这是正确的行为吗?如果是,我应该在标准的哪里查找以找出原因?
#include <iostream>
struct S {
int a;
S( int a ) : a( a ){ }
operator
int() const {
return a;
}
friend bool
operator<( const S & lhs, const S & rhs ){
return lhs.a > rhs.a;
}
};
int
main(){
std::pair< int, S > p1{ 0, 1 }, p2{ 0, 2 };
std::cout << (p1 < p2) << (p2 < p1) << std::endl;
}
最佳答案
在 C++17 中,[pairs.spec]定义了所有关系运算符。例如,operator<
被指定为:
template <class T1, class T2> constexpr bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y);
Returns:
x.first < y.first || (!(y.first < x.first) && x.second < y.second)
.
在 C++20 中,采用 <=>
,这看起来有点不同。也在 [pairs.spec] :
template<class T1, class T2> constexpr common_comparison_category_t<synth-three-way-result<T1>, synth-three-way-result<T2>> operator<=>(const pair<T1, T2>& x, const pair<T1, T2>& y);
Effects: Equivalent to:
if (auto c = synth-three-way(x.first, y.first); c != 0) return c; return synth-three-way(x.second, y.second);
哪里synth-three-way(x, y)
可以x <=> y
如果可能的话,否则做 x < y
然后y < x
(参见[expos.only.func])。
这里的问题是x <=> y
对于您的类型实际上是有效的,但与 x < y
有所不同,所以你会得到不同的结果。
关于c++ - 究竟标准的哪些部分需要涉及运算符 < 的重大更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70659217/