6

与えられた

struct Range{
    Range(double from, double to) : from(from), to(to) {}
    double from;
    double to;
    // if it matters to the compiler, we can add more fields here to make copying expensive
};

struct Box{
    Box(Range x, Range y) : x(x), y(y) {}
    Range x;
    Range y;
};

誰かが、コンパイラは最初からオブジェクトを内部で構築することにより、オブジェクトを完全にBox box(Range(0.0,1.0),Range(0.0,2.0))コピーすることを避けることができると言いました。Rangebox

実際にこれを行うコンパイラはありますか?

私自身の試みは成功していません。

4

2 に答える 2

8

コンパイラは、一時的なものから引数へのコピーを削除できます (通常は削除します)。コンパイラは、引数からメンバーへのコピーを省略できません。場合によってはこれらのコピーを除外することが技術的に可能かもしれませんが、関連する許可は与えられていません。標準のセクションは 12.8 [class.copy] パラグラフ 31 で、コピーを省略できる 4 つの状況を詳しく説明しています (正確なルールは少し重要です)。

  1. 名前を使用して名前付きの関数ローカル変数を返す場合。
  2. 式で名前付き関数ローカル変数を使用する場合throw
  3. 一時オブジェクトをコピーするとき。
  4. 例外を値でキャッチする場合。

名前付き引数をパラメーターとしてメンバー変数の構築に渡すことは、明らかに、これらの状況のいずれでもありません。

コピー省略のルールの本質的な背景は、一部のコンテキストでは、オブジェクトがいつ使用されるかを決定するのに関数の宣言で十分であるということです。オブジェクトを構築できる場所が構築時に明らかな場合は、省略できます。コンストラクターの呼び出し元は、オブジェクトが使用されるコンストラクターの宣言だけに基づいて決定することはできません。

于 2015-11-23T14:50:52.837 に答える