1. ホーム
  2. c++

[解決済み] コピーエリジョンと戻り値の最適化とは何ですか?

2022-03-22 01:10:40

質問

コピーエリジョンとは何ですか?戻り値の最適化(名前付き)とは何ですか?これらは何を意味しているのですか?

どのような場合に発生するのでしょうか?また、どのような制限がありますか?

解決方法は?

はじめに

技術的な概要については この回答へスキップする .

コピーエリジョンが発生する一般的なケースについて-。 この回答へスキップする .

コピーエリジョンとは、ほとんどのコンパイラが実装している最適化で、特定の状況下で余分な(高価になりうる)コピーを防止するためのものです。これにより、値による戻り値や値による受け渡しが実際に可能になります(制限が適用されます)。

これは、as-ifルールを無視した(ハ!)唯一の最適化の形です -。 オブジェクトのコピー/移動が副作用を伴う場合でも、コピーエリジョンを適用できます。 .

次の例は ウィキペディア :

struct C {
  C() {}
  C(const C&) { std::cout << "A copy was made.\n"; }
};
 
C f() {
  return C();
}
 
int main() {
  std::cout << "Hello World!\n";
  C obj = f();
}

コンパイラの & 設定により、以下のように出力されます。 はすべて有効です。 :

ハローワールド
コピーが作成されました。
コピーが作成されました。


ハローワールド
コピーが作成されました。


ハローワールド

これはまた、生成できるオブジェクトの数が少ないことを意味し、特定の数のデストラクタが呼び出されることに依存することもできません。コピー/ムーブコンストラクタやデストラクタの内部には、クリティカルなロジックを入れてはいけません。

コピーまたは移動のコンストラクタの呼び出しが省略された場合でも、そのコンストラクタは存在し、アクセス可能でなければなりません。これにより、コピーや移動のコンストラクタが非公開または削除されているなどの理由で、通常はコピーできないオブジェクトがコピーされないようにします。

C++17 : C++17 では、オブジェクトが直接返される場合、Copy Elision が保証されます。

struct C {
  C() {}
  C(const C&) { std::cout << "A copy was made.\n"; }
};
 
C f() {
  return C(); //Definitely performs copy elision
}
C g() {
    C c;
    return c; //Maybe performs copy elision
}
 
int main() {
  std::cout << "Hello World!\n";
  C obj = f(); //Copy constructor isn't called
}