0

コンパイラが名前付き戻り値の最適化 (NRVO) を実行できるようにするには、戻り値を関数本体の他の値より前に宣言する必要があることを理解しています。これは、例外が発生した場合のスタックの巻き戻しの順序が原因であると思われますが、よくわかりません。名前付きの戻り値が関数本体で最初に宣言されなければならない理由は何ですか?

class C{};
C f(){
    C ret; //NRVO possible
    return ret;
}
C g(){
    int i;
    C ret;  //NRVO not possible?
    return ret;
}

使用事例:

auto c = f();
auto c2 = g();

編集: これを理解するのを手伝ってくれてありがとう、すべての回答者に感謝します。チャンドラー・カルースの声明がここにあると疑い始めています。それを誤解します。戻り変数を最初に宣言することは重要ではないようです。

4

1 に答える 1

0

標準では、コピー省略に関して、変数の宣言/定義の順序に要件を課していません。標準では「実装が許可されている」と述べられていることに注意してください。これは、そうすべきである、する必要があるなどではありclangませgccMSVC

§12.8/31 では、コピー省略について説明しています。

[..] copy elisionと呼ばれるこのコピー/移動操作の省略は、次の状況で許可されます (複数のコピーを排除するために組み合わせることができます)。

— クラスの戻り値の型を持つ関数の return ステートメントで、式が関数の戻り値の型と同じ cv-unqualified 型を持つ不揮発性自動オブジェクト (関数または catch-clause パラメーター以外) の名前である場合、自動オブジェクトを関数の戻り値に直接構築することにより、コピー/移動操作を省略できます

[..]

于 2014-11-20T18:17:58.177 に答える