2

このクラスを考えてみましょう:

class C1 {
  C1(C1&&) = default;        // declare and define move ctor
};

C1 のムーブ ctor は最初の宣言で明示的にデフォルト設定されるため、標準の 8.4.2 では、関数が暗黙的に宣言されているかのように、同じ例外仕様 (ES) を持つことが示されています。次に、15.4/14 と 12.8/15 を使用して、その ES が であると結論付けることができnoexcept(true)ます。

次に、移動 ctor がクラス定義の外でデフォルト設定されていることを除いて、同じクラス C2 を考えてみましょう。

class C2 {
  C2(C2&&);                 // declare move ctor
}; 

C2::C2(C2&&) = default;     // define move ctor

C2 の move ctor の ES は? 最初の宣言ではデフォルトに設定されていないため、8.4.2/2 は適用されません。明示的な ES がないため、8.4.2/3 は適用されません。暗黙的に宣言されていないため、15.4/14 は適用されません。私が知る限り、それは 15.4/12 が適用されることを意味し、デフォルト関数 ES はnoexcept(false).

私が正しければ、それは C1 の move ctor が であることを意味しますがnoexcept(true)、C2 の概念的に同一の move ctor は ですnoexcept(false)

C2 についての私の推論は正しいですか?

4

2 に答える 2

6

はい、あなたの解釈は正しいです。宣言を公開すると、clang と gcc の両方があなたの推論に同意することを簡単に示すことができます。

#include <type_traits>

class C1
{
public:
  C1(C1&&) = default;        // declare and define move ctor
};

class C2 {
public:
  C2(C2&&);                 // declare move ctor
}; 

C2::C2(C2&&) = default;     // define move ctor

int
main()
{
    static_assert(std::is_nothrow_move_constructible<C1>{}, "");
    static_assert(!std::is_nothrow_move_constructible<C2>{}, "");
}
于 2015-04-16T23:55:35.273 に答える