関数 - 参照 の 参照 c++




参照修飾子のメンバ関数をオーバーロードするためのユースケースは何ですか? (3)

f()がこれのコピーであり変更されたFoo tempを必要とする場合は、代わりにtempをthis変更することができます

C ++ 11では、参照修飾子に基づいてメンバ関数をオーバーロードすることができます。

class Foo {
public:
  void f() &;   // for when *this is an lvalue
  void f() &&;  // for when *this is an rvalue
};

Foo obj;
obj.f();               // calls lvalue overload
std::move(obj).f();    // calls rvalue overload

どのように動作するのか理解していますが、そのユースケースは何ですか?

私はN2819が標準ライブラリのほとんどの代入演算子をターゲットを左辺に制限する(つまり代入演算子に " & "参照修飾子を追加する) ことを提案していましたが、 これは拒否されました 。 それは、委員会がそれに同行しないことを決めた潜在的なユースケースでした。 だから、合理的なユースケースは何ですか?


一方では、 &を参照修飾子として&を追加することで、一時的に無意味な関数がoperator=や内部状態を変更してvoidを返すなど、呼び出されることを防ぐことができます。

一方、rvalue参照があるときには、オブジェクトからのメンバを戻り値として移動するなどの最適化に使用できます。たとえば、 getName関数はstd::string const&またはstd::string&&返すことができます参照修飾子に追加します。

もう1つのユースケースは、 Foo& operator+=(Foo&)ような元のオブジェクトへの参照を返す演算子と関数です。代わりにrvalue参照を返すように特殊化でき、結果を移動可能にします。

TL; DR:誤った機能の使用や最適化を防ぐために使用します。


1つの使用例は、一時的なものへの割り当てを禁止することです

 // can only be used with lvalues
 T& operator*=(T const& other) & { /* ... */ return *this; } 

 // not possible to do (a * b) = c;
 T operator*(T const& lhs, T const& rhs) { return lhs *= rhs; }

参照修飾子を使用しないと、2つの不良の間で選択肢が残されます

       T operator*(T const& lhs, T const& rhs); // can be used on rvalues
 const T operator*(T const& lhs, T const& rhs); // inhibits move semantics

最初の選択肢は、移動セマンティクスを許可しますが、組み込み関数よりもユーザー定義型では動作が異なります(int型とは異なります)。 2番目の選択肢は、アサイメントを停止しますが、移動セマンティクスを排除します(たとえば、行列乗算ではパフォーマンスが低下する可能性があります)。

コメント内の@dypによるリンクも、(lvalueまたはrvalueのいずれかの)参照を割り当てる場合に便利な、もう一方の( && )オーバーロードの使用に関する拡張された議論を提供します。







qualifiers