标准的具体哪些部分需要涉及 operator <?

Exactly which parts of the standard require this breaking change involving operator <?

C++20 中进行了更改,我很难找到标准中的哪个位置可以查看发生此更改的信息。有人可以引用标准中告诉我会发生这种情况的部分吗?

我知道这个问题:Breaking change in std::tuple lexicographic comparison in C++20 with conversion operators?

但它没有回答我可以在标准中的何处找到它的问题。

对于 gcc 11.2 和 clang,此代码打印出 01(预期结果)和 -std=c++1710-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 做了一些不同的事情,所以您得到了不同的结果。