問題は、operator<<
が最初のパラメータではなく、2番目のパラメータとしてostream
になることです。そうすれば、myObject << std::cout
を行うことができますが、直観的ではなく、operator<<
が左結合であるため、コールをチェーンできなくなります。
メンバ関数ではなく、演算子をフレンドとして宣言することのもう1つの利点は、自動変換が行われることです。つまり、A
から派生しないがB(A const&)
コンストラクタを持つクラスB
がある場合は、std::cout << my_b;
を実行してA
に変換してから印刷することができます。
友人としてoperator<<
を定義することは、好きな場合はクラス内で行うことができます。あなたのコードは、引数が行くべき側面を指定するために、なぜ標準が許可されていません
class A {
int i;
friend std::ostream& operator<<(std::ostream& o, A const& a) {
o << a.i;
return o;
}
};
のように記述されるだろうか?のは、それがなかったふりをし、指定するleft_of
とright_of
キーワードを追加してみましょう:私たちはA a; B b; f(a + b);
を行う際
struct B;
struct A {
A left_of operator+(B const&) {
return *this;
}
};
struct B {
B right_of operator+(A const&) {
return *this;
}
};
今どうなりますか?各クラスには、このケースを扱う演算子があります。つまり、私たちは決定できません。とにかく変換の可能性のために多くの演算子が友人になるべきであることを見て、このようなことを許さないことは大きな問題ではなく、この種のあいまいさを防止します。 (もちろん、メンバーオペレータと自由なメンバーを定義することもできますが、これは非常に似たような問題を引き起こします)
ちなみに、あなたのfriend operator<<
の定義は何も返されません。チェーンアップを台無しにする。
[Operator overloading](http://stackoverflow.com/questions/4421706/operator-overloading)の可能な複製(特に[この回答を参照してください](http://stackoverflow.com/a/4421719/103167)) –