質問: move(ret(100)); cout << a << endl; cout << b << endl; cout << c << endl; } ```
回答: > > 以下のa, bが行っていることは同じと考えて問題ないでしょうか。 > > > いいえ。 違います。 `int&& a = ret(100);` は `ret(100)` によって作られる**一時的なオブジェクト**の参照を `a` として定義しています。 通常はそのような一時的なオブジェクトは完結式 (完全式とも言います) に解体されて無効になるのですが、参照で受けた場合に限って参照のスコープの終わりまで寿命が延長されるルールになっています。 この場合はどこかに `100` というオブジェクトがあって `a` という**別名**があるという状態です。 `int b = move(ret(100));` は普通にコピーしているだけです。 `std::move` はその名称に反してムーブする機能を持っていません。 もしそのクラスがムーブコンストラクタを持っている場合にそれを起動するような文脈を作り出すのが `std::move` の役割です。 `int` はムーブしませんからこの場面での `move` は無意味です。 `100` というオブジェクトが作り出されてそれを `b` にコピーした後に一時的なオブジェクトは解体されるという順序になります。 また、 `int` では効率的な問題にはなりませんが状況によっては `move` が無ければコンパイラがコピーを省略して直接構築する最適化をしても構わない文脈に適合する場合があります。 (C++17 以降では条件に合致すれば許容されるだけでなく必ずしなければならないように変更されました。) ムーブをした方が効率的とは限らないということには気を付けてください。 > > また、cの構文に問題はありますか。 > > > 文法規則上の問題はないはずですが `move` を書く意味はありません。 プログラムは機械が解釈するだけではなく人間も読み書きするものですから、書かれていることに意図 (プログラム的には機能していなくても) を読み取ろうとして混乱するということはあるかもしれません。 自分が書いたものでも後で読み返すとよくわからんというのもよくあることなので、理由なく冗長に書くのはお勧めできません。 (逆に言えば自分なりに特別な意図の表現として書くなら悪いわけではありませんが、イディオムとして確立しているものを除いてはコメントで書いておいた方が良いと思います。 時間を置くとびっくりするほど忘れます。)