bool operator==(const T&, const T&)と、クラス内でbool operator==(const T& other) constを定義する違いはなんですか?

投稿者: Anonymous

以下のコードのように、

  • メンバにbool operator==(const T&) constを定義する
  • グローバルにbool operator==(const T&, const T&)を定義する

この2つの違いは何でしょうか?
どちらを使うべきでしょうか?

code:

#include <iostream>

struct A{
    int x;
    bool operator==(const A& other) const {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
        return x == other.x;
    }
};

bool operator==(const A& a, const A& b){
    std::cout << __PRETTY_FUNCTION__ << std::endl;
    return a.x == b.x;
}

int main(){
    A a {1}, b {1};

    std::cout << (a==b) << std::endl;

    return 0;
}

output:

bool operator==(const A&, const A&)
1

解決

C++17現在は int32_t さん回答の通りなのですが、2020年内発行が予定されているC++20では両者の差異がさらに小さくなります。

メンバ関数として bool S::operator==(int) constを定義しておけば、従来通りS == intのオペランド順と、その逆順のint == Sの両方が自動的に有効になります。詳細は提案文書P1185R2を参照ください。

#include <iostream>
#include <iomanip>

struct S {
  int m_;

  bool operator==(int rhs) const {
    return m_ == rhs;
  }
};

int main()
{
  S a{1};
  std::cout << std::boolalpha
    << (a == 1) << 'n'   // OK
    << (1 == a) << 'n';  // C++20からOK
}

  • メンバにbool operator==(const T&) constを定義する
  • グローバルにbool operator==(const T&, const T&)を定義する

どちらを使うべきでしょうか?

技術的にはもう一つの選択肢「フレンド関数としてクラス内にfriend bool operator==(const T&, const T&)を定義する」があり得ます。

class T {
  // ...
public:
  friend bool operator==(const T&, const T&) { ... }
};

C++20仕様ではこのような関数を「Hidden Friends」として用語定義し、C++標準ライブラリ内では全面的に採用しています。(提案文書P1601R0, P1965R0

このHidden Friendsは、名前空間(namespace)の取り込み(using)にともなうトラブル回避のために導入されました。技術詳細はこちらの記事もご参考にください。

回答者: Anonymous

Leave a Reply

Your email address will not be published.