62475


以下のコードのように、

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

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

code:

[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;
    }
    
    
[/code]

output:

[code]

    bool operator==(const A&, const A&)
    1
    
[/code]


CC BY-SA 4.0
2019-12-26T08:06:03.407
61804
2020-01-23T04:01:35.620
2019-12-26T08:13:19.907
37013
37013
question
c++
bool operator==(const T&, const T&)と、クラス内でbool operator==(const T& other) constを定義する違いはなんですか？


挙げられた例のようにどちらでもうまくいく場合はどちらを使っても大丈夫です。挙動の違いはありません。

違いは、

  * メンパoperatorは非publicメンバにアクセスできる。グローバルoperatorはfriend宣言しない限り不可
  * グローバルoperatorの方が柔軟である。

後者について、たとえば例の中の`struct A`は整数との比較 `a == 3`
もしたくなるかもしれません。メンバoperatorでも`operator==(const int&)`を足せば可能ですが、逆順にした `3 ==
a`はメンバoperatorでは実現できません。


CC BY-SA 4.0
2019-12-26T08:36:58.093
61806
2019-12-26T09:12:34.403
2019-12-26T09:12:34.403
3475
3475
61804
answer


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

メンバ関数として `bool S::operator==(int) const`を定義しておけば、従来通り`S ==
int`のオペランド順と、その逆順の`int == S`の両方が自動的に有効になります。詳細は[提案文書P1185R2](http://www.open-
std.org/jtc1/sc22/wg21/docs/papers/2019/p1185r2.html)を参照ください。

[code]

    #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
    }
    
[/code]

  * GCC: <https://wandbox.org/permlink/QzfS3S9hatekob2W>
  * Clang: <https://wandbox.org/permlink/qCNY4i2wyKCvpS6d>

* * *

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

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

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

[code]

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

C++20仕様ではこのような関数を「Hidden
Friends」として用語定義し、C++標準ライブラリ内では全面的に採用しています。（提案文書[P1601R0](http://www.open-
std.org/jtc1/sc22/wg21/docs/papers/2019/p1601r0.pdf),
[P1965R0](http://www.open-
std.org/jtc1/sc22/wg21/docs/papers/2019/p1965r0.pdf)）

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


CC BY-SA 4.0
2020-01-23T03:30:19.400
62475
2020-01-23T04:01:35.620
2020-01-23T04:01:35.620
49
49
61804
answer