c++ - 究竟标准的哪些部分需要涉及运算符 < 的重大更改?

标签 c++ c++17 language-lawyer standards c++20

C++20 中进行了更改,我很难在标准中找到可以查看的位置以了解发生了此更改。有人可以引用一下标准中告诉我这会发生的部分吗?

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

但它没有回答我在标准中哪里可以找到这个问题。

使用 gcc 11.2 和 clang,此代码使用 -std=c++1710 打印出 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/

相关文章:

c++ - 奇数平台上的 std::byte

c++ - 为什么不修改关联容器的键?

c++ - 非阻塞 mlock()

c++ - 在 C++ 中的其他类中设置模板参数

c++ - move 构造函数而不实现,但它可以工作

c++ - 如何在需要旧式 unsigned char 的地方使用新的 std::byte 类型?

c++ - 前进或 move 与否;如何确定在类的使用上下文中哪个是首选?

c++ - GCC 对可能有效的代码抛出 init-list-lifetime 警告?

c++ - 使用 typedef 错误解析函数名称的全局 namespace 说明符?

c++ - 在参数列表中使用表达式的意外输出