質問: 500; f5(static_cast(x5));//出力値:501 cout << x5 << endl; //出力値:501(変わっている) f5(510); //出力値:511(リテラルもOK) } ```
回答: こんにちは。 右辺値参照は、参照の一種です。現在のところ参照は概ね3種類あると考えて良いと思います。 1. 普通の参照 `型名&`と書きます。constもないし&も1つだけのものです。 これは、変数に対する参照です。変数以外のもの(定数や一時領域)を参照できません。 2. const参照 `const 型名&`や、`型名 const&`と書きます。 これは、変数と定数と一時領域(計算結果)に対する参照です。 ただし、参照先が変数だった場合でもその変数の中身を変更できません。 3. 右辺値参照 `型名&&`と書きます。 これは、一時領域(計算結果。定数含む)に対する参照です。 参照先を変更できます。と言っても参照先はその文の終了と共に解放されますので、変更することに意味はほとんどありません。(ローカル変数として流用できるくらいです。) 一時領域は、例えば`foo(a+b);`のような呼び出しで、a+bの結果を保存している一時的な領域です。`foo(a+b);`等の文の中でこっそり獲得され、文が終わるとこっそり解放されています。 このように右辺値参照そのものはあまり有用なものではないのですが、参照先が一時変数(呼び出している側の文が終わると解放される。)と言う性質が有用です。 どうせ文が終わったら解放されるのですから、例えばstd::vector<>等の巨大な変数の記憶領域をコピーするのではなく、呼び出し先の関数へ渡してしまうことができます。(呼び出し元ではもう使えなくなる。すぐに解放されるので問題無し) 受け取り側はその事実を当てにして、高速なコードを記述できます。(ムーブ・セマンティクスと呼ばれています。) ``` std::vector foo(); void bar(std::vector&&); bar(foo()); ``` のような時に有用です。foo()が返却するstd::vector<>が巨大だった場合、一々その巨大なメモリをコピーしないようにプログラムすることが可能になるからです。使い方は難しいですが、結構ありがたいです。 提示されたサンプル・コードは上記の「3. 右辺値参照」で記載した内容が書かれています。正直、この使い方はあまり有用ではないと思います。 更に、static_cast()で渡した後の変数にアクセスするのは、意味論的に完全に間違った使い方です。 文法的には間違っていませんが、operator+を減算として定義するような間違いで、他のプログラマに対してたいへん不誠実な行為です。 学習のためと割り切って理解されることをお勧めします。