默认定义的移动构造函数的noexcept规则是什么?

mfu*_*chs 16 c++ pimpl-idiom move-semantics noexcept c++11

特别是std::vector与其相关的是,类型noexcept在可能的情况下是可移动的.

所以在声明= default像in 的移动构造函数时

struct Object1
{
    Object1(Object1 &&other) = default;
};
Run Code Online (Sandbox Code Playgroud)

std::is_nothrow_move_constructible<Object1>::value将是true每个成员(0在这里)Object1是nothrow-move-constructible,这在这里得到解答.

然而,如果仅声明移动复制构造函数,然后= default在以下代码中进行定义,会发生什么?

struct Object2
{
    Object2(Object2 &&other);
};
Object2::Object2(Object2 &&other) = default;
Run Code Online (Sandbox Code Playgroud)

随着G ++ 4.9.2 std::is_nothrow_move_constructible<Object2>::valuefalse,我要纪念这两个声明和定义noexcept,使其true.

现在我感兴趣的是实际规则是什么.特别是因为有效的现代C++中的第22项(Scott Meyers)似乎通过建议像我一样实现了pimpl-idiom移动构造函数来提供错误的建议Object2.

T.C*_*.C. 13

[dcl.fct.def.default]/P2:

如果函数在其第一个声明中明确默认,

  • 它隐含地被认为是constexpr隐含的声明是,和,
  • 它具有相同的异常规范,就好像它已被隐式声明(15.4).

如果函数在后面的声明中明确默认,则这些规则不适用,如后面的示例所示,因此,除了析构函数之外,noexcept(false)默认情况下该函数与大多数其他函数一样.

由于明确的违约可以在不同的翻译单元-而在PIMPL情况下,在不同的TU -有编译器看到类定义后,找出移动构造函数只是否会抛出,除非功能没有通用的方法在类定义中明确默认(即,在其第一次声明时).