簡體   English   中英

為什么默認三通運算符(spaceship <=>)生成相等運算符(==)而用戶定義三通運算符不?

[英]Why default three-way operator (spaceship <=>) generates equality operator (==) and user define three-way operator not?

考慮這段代碼:

#include <iostream>
#include <compare>

class A {
public:
  int i = {};

  std::strong_ordering operator<=> (A const& r) const
  {
    return i <=> r.i;
  }
};

void TestA()
{
    A a;
    A b;

    std::cout<< (a<b);    
    std::cout<< (a>b);
    std::cout<< (a<=b);
    std::cout<< (a>=b);
    //std::cout<< (a==b); //ERROR
    std::cout << 'E';
    //std::cout<< (a!=b); //ERROR
    std::cout << 'E';
    std::cout<< std::is_eq(a<=>b);
    std::cout<< std::is_neq(a<=>b) << std::endl;
}

class B {
public:
  int i = {};

  std::strong_ordering operator<=> (B const& r) const = default;

};


void TestB()
{
    B a;
    B b;

    std::cout<< (a<b);    
    std::cout<< (a>b);
    std::cout<< (a<=b);
    std::cout<< (a>=b);
    std::cout<< (a==b);
    std::cout<< (a!=b);
    std::cout<< std::is_eq(a<=>b);
    std::cout<< std::is_neq(a<=>b) << std::endl;
}

class C {
public:
  bool b = {};
  int v1 = {};
  int v2 = {};

  std::strong_ordering operator<=> (C const& r) const
  {
      return (b?v1:v2) <=> (r.b?r.v1:r.v2);
  }

  bool operator== (C const& r) const
  {
      return std::is_eq(*this<=>r);
  }

};

void TestC()
{
    C a;
    C b;

    std::cout<< (a<b);    
    std::cout<< (a>b);
    std::cout<< (a<=b);
    std::cout<< (a>=b);
    std::cout<< (a==b);
    std::cout<< (a!=b);
    std::cout<< std::is_eq(a<=>b);
    std::cout<< std::is_neq(a<=>b) << std::endl;
}


int main()
{    
    TestA();
    TestB();
    TestC();

    return 0;
}

https://wandbox.org/permlink/SLmLZOc18RaJV7Mu

刪除評論以獲取錯誤。

首先我想問一下為什么默認的三路運算符的行為與用戶定義的運算符不同?

其次,這個問題的解決方案對於 class C是否正確,還是應該以不同的方式處理?

這只是一個簡單的例子,我對數十個字段和聯合有更復雜的情況(如果你不明白我的意思,請查看一些英特爾 API;))。

編輯:

這個問題Equality operator does not get defined for a custom spaceship operator implementation in C++20重點是為什么用戶定義的 3 路運算符沒有默認相等運算符,我想知道為什么默認值和用戶存在差異定義行為?

編輯2:

我在示例中稍微修改了 class C以描繪更多現實生活中的問題(當默認運算符不是有效的解決方案時)。 我還想澄清一下,我想知道這些差異背后的原因(用戶定義和默認運算符之間),以便能夠評估我的現實生活中的解決方案是否正確(類似於C ),因為我確實更看重代碼可維護性而不是性能對於我現在正在工作的部分代碼。

將相等和排序分開的主要原因是性能。 如果您有一個排序操作是用戶定義的類型,那么通常情況下,您可以編寫一個用戶定義的相等測試操作,該操作在執行相等測試時更有效。 因此,該語言應該鼓勵您通過不使用operator<=>進行直接相等測試來編寫它。

這僅適用於用戶定義的排序/相等操作。 默認排序是按成員的,默認的相等操作也是按成員的。 並且由於排序意味着相等,因此默認排序也默認相等是合理的。

是的,他們可以讓人們把它拼出來,但沒有一個很好的理由 operator<=>旨在使選擇默認排序變得容易; 讓你為其中一個已經暗示的東西寫兩個聲明是沒有意義的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM