C++には参照が2種類あって、それが左辺値参照T&と右辺値参照T&&
本当は怖くないムーブセマンティクス - yohhoyの日記(別館)
参照宣言 - cppreference.com
右辺値参照とは
- 一時オブジェクトの生存期間を延長するもの
- std::moveを使って作り出すことが多い?
- 実際にやってることはキャストっぽい
- llvm/llvm-project move.hにある実装 は
return static_castをしている
- llvm/llvm-project move.hにある実装 は
- 実際にやってることはキャストっぽい
- T&&を受け取る関数を呼び出すためのものだと思っている
- つまりnew T(other)だとコピーコンストラクタが呼ばれるが、new T(std::move(other))だとムーブコンストラクタが呼ばれる、みたいな使い分けをするためだけの存在
- 少なくとも仕様に沿った説明ではなさそうだが……
T&& xがあったとき、xという式はT&として評価される- 初見だとかなり直感に反するが、
T::T(U&& x): a_(std::move(x.a)), b_(std::move(x.b)) {}のようなコードを考えると納得x.aの時点でmoveされるとx.bを参照したいときにこまります
- 初見だとかなり直感に反するが、
- 参照なので参照元が別途必要
std::vector<T> vの要素をT&& eに入れてからv.pop_back()したのちstd::move(e)とかやっても駄目(1敗)
- 例えばstd::vectorを受け取ってすべての値を2倍にした新しいvectorを返す、みたいな関数は以下のようになる(参考サイトより):
-
typedef std::vector<int> IntVec; IntVec twice_vector(IntVec a) { for (auto& e : a) e *= 2; return std::move(a); } IntVec v = { /*...*/ }; IntVec w = twice_vector( std::move(v) );- こうすると、引数
aはコピーコンストラクタではなくムーブコンストラクタによって構築されるのでパフォーマンスが良くなるということ? - 呼び出し元が
std::moveを使わなかったらコピーになってしまうが、仕方ないということなんだろうか- 逆に
IntVec&&を受け取る関数にすると、std::moveを使わずに呼び出すことができなくなるので不便、という説明が記事にある
- 逆に
return std::move(a)においてstd::moveは不要である可能性がある- コンパイラはこういうときに暗黙のムーブをすることがあるらしい?ため
- implicit behaviorやめてね~
- コンパイラはこういうときに暗黙のムーブをすることがあるらしい?ため
- こうすると、引数
-