7

私が間違っていなければ、const 参照と右辺値参照の両方が右辺値にバインドできると思います。前者を返す関数と後者を返す関数の間に実際的な違いはありますか?

編集。前者を変更することはできませんが、右辺値を変更することに関心があるのはなぜですか? それは理にかなっていますか?

4

2 に答える 2

16

const左辺値参照は何にでもバインドできます。右辺値参照は、非右辺値にのみバインドできconstます。

            non-const lvalue   const lvalue   non-const rvalue   const rvalue
const T&    yes                yes            yes                yes
T&&         no                 no             yes                no

ご覧のとおり、それらは大きく異なります。

さらに、関数呼び出しが左辺値参照を返す場合、その式は左辺値ですが、関数呼び出しがオブジェクトへの右辺値参照を返す場合、その式は xvalue です。

関数呼び出しは、結果の型が左辺値参照型または関数型への右辺値参照の場合は左辺値、結果の型がオブジェクト型への右辺値参照の場合は xvalue、それ以外の場合は prvalue です。

右辺値を変更したい場合については、まさにこれが移動セマンティクスのすべてです。次の関数呼び出しを検討してください。

void func(std::string);

func(std::string("Hello"));

std::string("Hello")は、一時オブジェクトを作成する右辺値です。この右辺値でパラメーターを初期化するときstd::string、右辺値参照を取るコンストラクター、移動コンストラクターが選択されます。次に、このコンストラクターは右辺値から何かを盗みます。これは通常、完全なコピーを行うよりもはるかに高速です。一時的なものだとわかっているので盗むことができます。

const左辺値参照または右辺値参照を返す必要がある場合については、次のとおりです。

  • 左辺値参照を返すことconstは、「内部」オブジェクト (おそらくクラスのメンバー) を読み取るためのアクセスを許可したいが、変更を許可したくない場合に最もよく使用されます。

  • 右辺値参照を返すことは、呼び出し元のコードを「内部」オブジェクト (おそらくクラスのメンバー) から移動できるようにする場合に最もよく使用されます (まったく一般的ではありません)。そのため、一時的に返されたオブジェクトから移動する代わりに (値で返される場合のように)、文字通り内部オブジェクトから移動します。

    constこれは左辺値以外の参照でも実現できますが、その場合は明示的に参照する必要がありstd::moveます。

したがって、右辺値参照を返す必要がある可能性はほとんどありません。

std::forwardのような戻り値の型はありませんT&&。ただし、 のタイプによって右辺値参照である場合とそうでない場合があるため、これは欺瞞的ですTユニバーサル リファレンスを参照してください。

于 2013-03-28T12:23:44.270 に答える
4

前者を返す関数と後者を返す関数の間に実際的な違いはありますか?

質問の形式が悪いようです。定数の左辺値参照を返す関数は、読み取りのためだけにオブジェクトへのアクセスを提供しますが、右辺値参照を返す関数は、移動のためのアクセスを提供します。つまり、呼び出し元は、参照されたオブジェクトの内容を取得して別のオブジェクトに移動できます。物体。それらは決して比較できません。

どちらの場合も、参照は、それを返す関数の最後を超えて有効期間が続くオブジェクトを指す必要があります。そうしないと、呼び出し元がその参照を使用したときに未定義の動作でトリップします。

于 2013-03-28T13:05:17.070 に答える