ムーブセマンティクス(Move Semantics)はテクニックにすぎない
正確には、C++0xではムーブセマンティクスを実現"しやすく"なっただけで、
ムーブ自体は昔からのテクニックに過ぎない。
という事をやっと理解したっぽい?メモ。
#include <iostream> #include <vector> #include <string> std::vector<std::string> add_bar(std::vector<std::string> lhs) { lhs.push_back("bar"); return lhs; } int main(){ const size_t v_size = 100000; std::vector<std::string> v1; std::vector<std::string> v2; v1.reserve(v_size*2); for(size_t i=0; i < v_size; ++i){ v1.push_back("foo"); } // クソみたいに重いコピーが起こる v1 = add_bar(v1); // moveされてすぐ終わる v1 = add_bar( std::move(v1) ); // この時点でv1には100000個の"foo"と2個の"bar"が入っている。 // moveする。つまり、"ムーブコンストラクタ(or代入演算子)を呼び出す"。 v2 = std::move(v1); // この時点でv1には何も入っていない。 // この時点でv2には100000個の"foo"と2個の"bar"が入っている。 // そしてその処理は、std::vectorの中身を書いた人がポインタのつなぎ替え等で"実装したもの"である。 return 0; }
============================
Move Semanticsが???となる人の突っかかりポイントは(自分がまさにそうだったが)、新しく特別なメモリ上の操作が自動、あるいは新しい構文で行われるんじゃないと思っている所。
実際は単に、移動してよい場合というのを区別できるムーブコンストラクタやムーブ代入演算子が定義されただけで、中の実装は単なるポインタの操作である。(だから配列がポインタ等を用いず生で使ってある場合にはコピー==ムーブ)
実際にはSTLの内部処理とかに使われていて、一般のプログラマが気にする事ではないけれども、どういう事が行われているかを知っているのと知らないのではだいぶ違うよね的な。