【问题标题】:What are the rules for noexcept on default defined move constructors?默认定义的移动构造函数上的 noexcept 规则是什么?
【发布时间】:2015-04-24 00:27:07
【问题描述】:

特别是与std::vector 相关,重要的是类型可以noexcept 尽可能移动。

所以当声明一个移动构造函数= default就像在

struct Object1
{
    Object1(Object1 &&other) = default;
};

std::is_nothrow_move_constructible<Object1>::value 将是 true,因为 Object1 的每个成员(此处为 0)都不是抛出移动可构造的,答案是 here

但是,如果只声明移动复制构造函数,然后像下面的代码那样定义 = default,会发生什么?

struct Object2
{
    Object2(Object2 &&other);
};
Object2::Object2(Object2 &&other) = default;

使用 g++ 4.9.2 std::is_nothrow_move_constructible<Object2>::valuefalse,我必须将声明和定义都标记为 noexcept 以使其成为 true

现在我感兴趣的是实际规则是什么。 特别是因为Effective Modern C++ (Scott Meyers) 中的第 22 项似乎通过建议实现 pimpl-idiom move 构造函数就像我对Object2 所做的那样给出了错误的建议。

【问题讨论】:

    标签: c++ c++11 move-semantics pimpl-idiom noexcept


    【解决方案1】:

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

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

    • 如果隐式声明是,则隐式认为是constexpr,并且,
    • 它具有与隐式声明 (15.4) 相同的异常规范。

    如果函数在以后的声明中显式默认为默认值,则这些规则不适用,如您后面的示例所示,因此,除析构函数外,默认情况下,该函数与大多数其他函数一样被视为 noexcept(false)

    由于显式默认值可以在不同的翻译单元中 - 在 pimpl 的情况下, 在不同的 TU 中 - 编译器仅在查看类定义后无法确定移动构造函数是否会抛出,除非函数在类定义中显式默认(即,在其第一次声明时)。

    【讨论】:

      猜你喜欢
      • 2020-05-08
      • 2021-04-07
      • 2013-09-10
      • 2019-12-09
      • 1970-01-01
      • 1970-01-01
      • 2015-07-03
      • 2017-12-05
      • 1970-01-01
      相关资源
      最近更新 更多