相关疑难解决方法(0)

C++20 行为用相等运算符破坏现有代码?

我在调试这个问题时遇到了这个问题

我一直将其精简为仅使用Boost Operators

  1. 编译器资源管理器C++17 C++20

    #include <boost/operators.hpp>
    
    struct F : boost::totally_ordered1<F, boost::totally_ordered2<F, int>> {
        /*implicit*/ F(int t_) : t(t_) {}
        bool operator==(F const& o) const { return t == o.t; }
        bool operator< (F const& o) const { return t <  o.t; }
      private: int t;
    };
    
    int main() {
        #pragma GCC diagnostic ignored "-Wunused"
        F { 42 } == F{ 42 }; // OKAY
        42 == F{42};         // C++17 OK, C++20 infinite …
    Run Code Online (Sandbox Code Playgroud)

c++ spaceship-operator c++17 c++20

107
推荐指数
1
解决办法
4526
查看次数

三向比较运算符总是有效吗?

Herb Sutter在他的"宇宙飞船"运营商提案(第12.2节,第12页底部)中说:

基于所有内容<=>及其返回类型:此模型具有主要优势,与先前的C++提议和其他语言的功能相比,此提案有一些独特之处:

[...]

(6)效率,包括最终实现用于比较的零开销抽象:绝大多数比较总是单通道.唯一的例外是生成,<=并且>=在支持部分排序​​和相等的类型的情况下.对于<单通是基本实现了零开销的原则,以避免重复平等的比较,如struct Employee { string name; /*more members*/ };在使用的struct Outer { Employeee; /*more members*/ };-今天的对比违反零开销抽象,因为operator<Outer执行冗余相等比较,因为它执行if (e != that.e) return e < that.e;横贯平等前缀 e.name两次(如果名称相同,则遍历Employee两次其他成员的相等前缀),这通常无法优化.正如Kamiński所指出的,零开销抽象是C++的支柱,并且首次实现它的比较是这种设计的一个重要优势<=>.

但他给出了这个例子(第1.4.5节,第6页):

class PersonInFamilyTree { // ...
public:
  std::partial_ordering operator<=>(const PersonInFamilyTree& that) const {
    if (this->is_the_same_person_as ( that)) return partial_ordering::equivalent;
    if (this->is_transitive_child_of( that)) return partial_ordering::less;
    if (that. …
Run Code Online (Sandbox Code Playgroud)

c++ operators spaceship-operator c++20

20
推荐指数
3
解决办法
2064
查看次数

为什么pair的比较运算符比用户提供的运算符&lt;更喜欢转换?

切换到 C++20 后,我发现我们的一些测试失败了。以下代码的输出在 C++17 和 C++20 模式之间有所不同:

https://godbolt.org/z/hx4a98T13

class MyString
{
public:
    operator char const *() const
    {
        std::printf("convert ");
        return nullptr;
    }

    bool operator<(MyString const & other) const
    {
        std::printf("MyString::operator< ");
        return 1;
    }
};

int main()
{
    MyString s1;
    MyString s2;
    std::printf("s1 < s2 = %d\n", s1 < s2);

    std::pair<MyString, MyString> pair1;
    std::pair<MyString, MyString> pair2;
    std::printf("pair1 < pair2 = %d\n", pair1 < pair2);
}
Run Code Online (Sandbox Code Playgroud)
/// C++17
MyString::operator< s1 < s2 = 1
MyString::operator< pair1 < pair2 = 1 …
Run Code Online (Sandbox Code Playgroud)

c++ comparison-operators c++20

5
推荐指数
1
解决办法
148
查看次数