質問文やコメントから受ける印象として、ムーブセマンティクス、コピー/ムーブ操作、右辺値参照型、RVO などの概念を混同しているように見受けられます。
以下のコードがmove semanticsを行っている
ムーブセマンティクス(move semantics)は "行う" といった具体的な動作を指すというより、オブジェクトがムーブ(移動)したかのように見なせるという設計上の "考え方" と解釈する方が適切です。
auto v = makeBigVector();
はコピーではないのでしょうか。
ここは C++11〜C++14までと、C++17以降でC++仕様上の定義が異なります。ただし、いずれもコピー操作ではありません。
- C++14まで: 原則として、関数戻り値オブジェクトから変数
v
へと ムーブ代入 されます。ただし大半のC++コンパイラで RVO(Return Value Optimization) が適用され、ムーブもコピーも行われずに関数戻り値オブジェクトがそのまま変数v
の値となる可能性が高いです。
- C++17以降: コピー省略保証(RVO保証)されるため、ムーブもコピーも発生しません。常に、関数戻り値オブジェクトがそのまま変数
v
の値となります。
別の表現では、C++14まではコンパイラの最適化オプションだったRVOが、C++17以降では100%保証される最適化機能となりました。
move semanticsさせたいときはauto&&で受け取らないといけないと思っていました。
質問文面からは、ムーブセマンティクスをサポートするクラスの 「提供側(内部実装)」 と 「利用側(外部仕様)」 の観点が混同されているようにも思えます。さらに言えば、auto&&
とクラス型&&
もその意味合いは全く異なります。
元の文意を残しつつ正確な説明をするなら、「ムーブセマンティクスに対応するクラスT
の提供者は、右辺値参照型T&&
を用いてムーブ操作を実装する必要がある」 でしょうか。
ムーブセマンティクスをサポートするクラス(ここではvector<int>
)を利用するだけであれば、必要になるのはstd::move
関数の適切な利用だけです。右辺値参照型vector<int>&&
やauto&&
を使わなくとも、ムーブ操作を利用できます。
この辺りの用語・概念はどうしても複雑になっているため、さまざまな解説記事や書籍等をあたって理解を進めてください。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/09/03 07:13