私はcppreference.comnoexcept
を見てきましたが、 の仕様が示されていないようですstd::function(std::function&&)
。これは私にはかなり奇妙に思えます。この場合、規格は実際に nothrow を保証していないのでしょうか?
4 に答える
標準を引用する(要求に応じて):
C++11 §20.8.11.2.1/6 (N3290 から):
function(function&& f);
template <class A> function(allocator_arg_t, const A& a, function&& f);
効果: の場合!f
、*this
ターゲットがない。f
それ以外の場合、 のターゲットをのターゲットにムーブ構築し、未指定の値を持つ有効な状態の*this
ままにします。f
申し訳ありませんnoexcept
が、移動中のコンストラクターはありません。
関連する欠陥レポート 2062がまだ開いていますが、いわば別の方向に進んでいnoexcept
ます。
移動コンストラクターをスローする callable をサポートすることが意図されている可能性があります。しかし、それは合理化の方向への憶測にすぎません。たとえば、そのような関数オブジェクトのベクトル内のバッファーの再割り当てを想像してみてください。ここで、元のオブジェクトを移動しようとし、途中でそのうちの 1 つがスローされます (これは Abrahams などによる元の例だと思います)。 . ぶっちゃけ、元に戻すことは保証できませんし、前に進めることもできません。そのため、再割り当てが失敗し、再割り当てを引き起こした操作が失敗し、ベクトルが無効な状態になります. 呼び出し可能なオブジェクトの非スロー移動の要件は、最適化されたベクトルの再割り当て (など) を含む、関数オブジェクトのそのような一般的な使用法をサポートしていたでしょう。どの私見も、意図が本当にこのトレードオフを行うことであったかどうかを疑っています。
他の答えはどれも本当に意味がありません。 にstd::function
はnoexcept
デフォルトのコンストラクターとnoexcept
swap
メソッドがあるため、実装者は常に移動コンストラクターを次のように定義できます。
function(function&& other) noexcept
: function()
{
swap(*this, other);
}
上記を考えると、委員会がコンストラクターの移動を拒否した理由がわかりませんnoexcept
。std::function
いずれの場合も、ラッパーを作成して を保持し、この手法を使用して移動することで、問題を回避できます。
function
オブジェクトは、任意のユーザー定義の呼び出し可能なオブジェクトを格納できると思います。オブジェクトを移動するfunction
と、含まれているユーザー定義オブジェクトも移動されますが、例外なく移動できるという保証はありません。