在课外定义的默认移动操作的异常规范是什么?

Kno*_*abe 2 standards move exception-specification c++11

考虑这个课程:

class C1 {
  C1(C1&&) = default;        // declare and define move ctor
};
Run Code Online (Sandbox Code Playgroud)

因为C1的移动ctor在其第一个声明中被明确默认,所以标准的8.4.2告诉我们它具有相同的异常规范(ES),就好像该函数已被隐式声明一样.然后我们可以使用15.4/14和12.8/15来得出其ES的结论noexcept(true).

现在考虑一个C2相同的类,除了它的移动ctor在类定义之外默认:

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

C2::C2(C2&&) = default;     // define move ctor
Run Code Online (Sandbox Code Playgroud)

C2移动ctor的ES是多少?因为它的第一次声明没有违约,所以8.4.2/2不适用.因为它没有明确的ES,所以8.4.2/3不适用.因为没有隐含声明,15.4/14不适用.据我所知,这意味着15.4/12适用,它表示默认函数ES是noexcept(false).

如果我是对的,这意味着C1中的移动ctor是noexcept(true),但C2中的概念相同的移动ctor是noexcept(false).

我对C2的推理是否正确?

How*_*ant 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>{}, "");
}
Run Code Online (Sandbox Code Playgroud)