STLとmoveセマンティクス
STLとmoveセマンティクス(2 : 追記)
非const参照を渡すだけとの比較コードも書いてみました。
http://ideone.com/PAc2B
参照に比べた利点ですが、一時変数を渡せるというのもありますね。
後は・・・・いろいろありますが、Cryoliteさんによると、
http://bit.ly/oDt1gs
のような利点があるようです。私は半分位しか仰っていることを理解できていません><。精進します!
ということで追記メモ終わりです。新しいほうが前で申し訳ないですが、weblogの特徴ということでここは1つ......。
STLとmoveセマンティクス(1)
"参照で引数を渡して関数内でオブジェクトを操作する"という動作をC++0xのmoveセマンティクスを使えば撲滅できるということを聞いて、コピーコストの問題が一番つきまといそうな"STL"*1でできるかどうかを確認してみました。
テストコードは以下の物です(リンク先でも確認可能)
http://ideone.com/UPWwT
#include <iostream> #include <vector> struct hoge { hoge(){} hoge( const hoge & h ) { std::cout << "copy\n"; } ~hoge() { std::cout << "デストラクタ\n"; } }; std::vector< hoge > foo( std::vector< hoge > h ) { std::cout << "foo\n"; return std::move( h ); //将来的にはmoveしなくても自動でmoveされる(今のgcc4.5.1だと無理) } int main() { { std::vector< hoge > h; h.push_back( hoge() ); std::cout << "-------------push copy-------------------\n"; h = foo( h ); } std::cout << "--------------------------------------------\n"; { std::vector< hoge > h; h.push_back( hoge() ); std::cout << "-------------push copy-------------------\n"; h = foo( std::move( h ) ); } return 0; }
出力
copy デストラクタ -------------push copy------------------- copy foo デストラクタ デストラクタ -------------------------------------------- copy デストラクタ -------------push copy------------------- foo デストラクタ
ちなみに、現在のgccではfooの戻り値にstd::moveを使っていますが、C++0xの規格として自動変数と参照ではない仮引数を戻り値として使用する場合は暗黙でmoveされることが決まっているそうです*2。
おおー・・・・確かにコピー渡しなのにコピーコストがかかっていません。
これはstd::moveによって所有権の放棄?*3がされてますね。これで引数を渡す時にプログラマがmoveを明示的に行うことによって、意図せず書き換えをすることはなさそうです。
コピーコストが0に、書き換えを意図する時は明示的に関数先に渡してやる、しかもプログラマが明示的にそうしていなければ関数先でも元オブジェクトは書き換えられない、という良いことづく目だとおもいます。何か思っていることを説明しづらいなぁ.....w。もしかしたらここら辺は後で表現しやすい文章が出てきたら書き換えるかも....。
というメモ書きdone......!