在默认定义的move构造函数中,noexcept的规则是什么? [英] What are the rules for noexcept on default defined move constructors?

查看:146
本文介绍了在默认定义的move构造函数中,noexcept的规则是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尤其是与std::vector关联,在可能的情况下,使类型noexcept可移动是很重要的.

Especially in connection with std::vector it is important that types are noexcept movable when possible.

因此,在声明移动构造器= default时,如

So when declaring a move constructor = default like in

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

std::is_nothrow_move_constructible<Object1>::value将是true,因为Object1的每个成员(此处为0)都不是可移动构造的,这得到了回答

std::is_nothrow_move_constructible<Object1>::value will be true as every member (0 here) of Object1 is nothrow-move-constructible, which is answered here.

但是,如果仅声明了移动副本构造函数,然后又像下面的代码中那样定义了= default,会发生什么呢?

Yet what happens if the move copy constructor is only declared and then later = default defined like in the following code?

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

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

With g++ 4.9.2 std::is_nothrow_move_constructible<Object2>::value is false and I have to mark both the declaration and the definition as noexcept to make it true.

现在我感兴趣的是实际规则. 特别是由于 rel ="nofollow noreferrer">有效的现代C ++ (斯科特Meyers)建议通过像我对Object2所做的那样实现pimpl-idiom move构造函数,似乎给出了错误的建议.

Now what I am interested in is what the actual rules are. Especially since Item 22 in Effective Modern C++ (Scott Meyers) seems to give ill advice by suggesting to implement the pimpl-idiom move constructor like I did with Object2.

推荐答案

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

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

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

If a function is explicitly defaulted on its first declaration,

  • 如果隐式声明将是,则将其隐式认为是constexpr,并且
  • 它具有与隐式声明(15.4)相同的异常规范.
  • it is implicitly considered to be constexpr if the implicit declaration would be, and,
  • it has the same exception specification as if it had been implicitly declared (15.4).

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

These rules do not apply if the function is explicitly defaulted on a later declaration, as in your later example, so instead, except for destructors, the function is considered noexcept(false) by default like most other functions.

由于显式默认值可以位于不同的翻译单元中,而在pimpl情况下,位于位于不同的TU中,因此,仅在看到类定义之后,编译器没有通用的解决方法除非在类定义中(例如,在其第一个声明处)显式默认该函数,否则move构造函数是否将抛出.

Since the explicit defaulting can be in a different translation unit - and in the pimpl case, is in a different TU - there's no general way for the compiler to figure out after seeing the class definition only whether the move constructor will throw, unless the function is explicitly defaulted in the class definition (i.e., at its first declaration).

这篇关于在默认定义的move构造函数中,noexcept的规则是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆