この質問は、「値渡しパラメーターと noexcept を持つコンストラクター」の二重です。その質問は、値による関数引数の有効期間管理が呼び出し元の関数によって処理されることを示しました。したがって、呼び出し元は発生するすべての例外を処理し、呼び出された関数はそれ自体をマークできますnoexcept
。出力端が でどのように処理されるのか疑問に思っていますnoexcept
。
MyType MyFunction( SomeType const &x ) noexcept;
//...
void MyCaller()
{
MyType test1 = MyFunction( RandomSomeType() );
MyType test2{ MyFunction( RandomSomeType() ) };
//...
test1 = MyFunction( RandomSomeType() );
test2 = std::move( MyFunction(RandomSomeType()) );
MyFunction( RandomSomeType() ); // return value goes to oblivion
}
戻り値が 内で正常に作成されたとしましょうMyFunction
。MyType
そして、適切な特別なメンバー関数 (copy/move-assignment/construction) が ではない可能性があるとしましょうnoexcept
。
- 呼び出された関数から呼び出し元への戻り値の転送に関する RVO/NRVO/Whatever-from-C++11 ルール
noexcept
は、適切な特別なメンバー関数のステータスに関係なく、転送が常にスローなしで成功することを意味しますか? - 前の質問に対する答えが「いいえ」の場合、戻り値転送がスローされる場合、例外は呼び出された関数または呼び出し元に対してカウントされますか?
- 前の質問に対する答えが「呼び出された関数」である場合、プレーン
noexcept
マーカー onMyFunction
によって が呼び出されstd::terminate
ます。MyFunction
のnoexcept
プロファイルを何に変更する必要がありますか? Usenet でこれについて尋ねたところ、ある回答者はstd::is_nothrow_move_assignable<MyType>::value
. (MyCaller
戻り値を使用するいくつかの方法を使用しましたが、どの方法が使用されているかMyFunction
はわかりません! 答えはすべてのケースをカバーする必要があります。)MyType
がコピー可能で移動不可能に変更された場合、違いはありますか?
したがって、2 番目と 3 番目の質問の最悪のケースが正確であるnoexcept
場合、戻り値の型にスロー可能な動きがある場合、値によって返される関数はプレーンを持つことはできません! is_nothrow_move_assignable
現在、スロー可能な移動を持つ型はまれである必要がありますが、テンプレート コードは、値による戻り値が使用されるたびに、それ自体を「ダーティ」にする必要があります。
呼び出された関数を責任あるものにするのは壊れていると思います:
MyType MyFunction( SomeType const &x ) noexcept( ??? )
{
//...
try {
return SOME_EXPRESSION;
// What happens if the creation of SOME_EXPRESSION succeeds, but the
// move-assignment (or whatever) transferring the result fails? Is
// this try/catch triggered? Or is there no place lexically this
// function can block a throwing move!?
} catch (...) {
return MyType();
// Note that even if default-construction doesn't throw, the
// move-assignment may throw (again)! Now what?
}
}
この問題は、少なくとも私には、呼び出し元の側で修正可能 (ムーブ代入をtry
/でラップするだけ) のように見えcatch
ますが、呼び出された関数の側からは修正できません。C++ のルールを変更する必要があるとしても、呼び出し元がこれを処理する必要があると思います。または、少なくとも何らかの欠陥レポートが必要です。