質問: {1, 2, 3}; twice_vec_2(a); return 0; } ``` 当方の認識では、パフォーマンス的に参照渡しで書いたコードが劣ることはないと理解しています。 この差は、ムーブで書いたほうが各変数がimmutableなように書いてあって分かりやすい以外に何かあるのでしょうか。 どういう時はどっちのほうが良い、などあるのでしょうか。 (極端な話、今までポインタや参照渡しで書かれていたコードは全てムーブセマンティクスで書いたほうが良いというような話なのでしょうか) 何卒、よろしくお願いいたします。
回答: 参照が適さないケースとして 圧縮されたデータを展開するシナリオを考えます。 ``` std::vector inflate1(const std::vector& zipped){ size_t len = *(size_t*)zipped.data(); std::vector result(len); // なんらかのデータ展開処理 return result; } void inflate2(const std::vector &zipped, std::vector &result){ size_t len = *(size_t*)zipped.data(); result.swap(std::vecor(len)); // なんらかのデータ展開処理 } int main(){ std::vector zip{100,0,0,0,0xff,0xff}; { std::vector result = inflate1(zip); } { std::vector result; inflate2(zip, result); } } ``` この場合、NRVOを用いた`inflate1`の方がわかりやすく、効率もよいでしょう。 inflate2は、呼ばれた時点で`result`に何が入っているのか・どういう状況なのかがわかりません。 そのため、解放および初期化が必要になります。 上ではムーブセマンティクスを使いませんでした。 というのも、現状のムーブセマンティクスには欠陥があり必要でないなら使わない方がパフォーマンス上よい と私は思っているからです。 その欠陥は、ムーブした後の残骸であろうとデストラクタが呼び出される事です。 逆に使う必要がある時というのは限られています。 それは、 * コピー代入が使えないとき * 参照が使えないとき です。 思いつくのは・・・ ``` #include #include #include int main(){ using namespace std; unique_ptr t = make_unique('Q'); for(int i=38;i<100;i++){ unique_ptr s = make_unique(i); // 適当な条件式 if(rand() % 100 > 93){ t = std::move(s); break; } } if(t) cout << *t << endl; } ``` こんな感じでしょうか