在默认定义的move构造函数中,noexcept的规则是什么? [英] What are the rules for noexcept on default defined move constructors?
问题描述
尤其是与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>::value
是false
,我必须将声明和定义都标记为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
.
现在我感兴趣的是实际规则.
特别是由于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屋!