特别是与std::vector
重要的是类型是noexcept
尽可能移动。
所以在声明移动构造函数时= default
like in
struct Object1
{
Object1(Object1 &&other) = default;
};
std::is_nothrow_move_constructible<Object1>::value
将true
作为每个成员(此处为 0)Object1
是不可投掷移动可构造的,已回答here https://stackoverflow.com/questions/18290523/does-a-default-move-constructor-equals-to-a-member-wise-move-constructor.
然而,如果仅声明移动复制构造函数然后稍后会发生什么= default
像下面的代码一样定义?
struct Object2
{
Object2(Object2 &&other);
};
Object2::Object2(Object2 &&other) = default;
使用 g++ 4.9.2std::is_nothrow_move_constructible<Object2>::value
is false
我必须将声明和定义标记为noexcept
做到这一点true
.
现在我感兴趣的是实际规则是什么。
特别是自从第 22 条以来有效的现代 C++ https://rads.stackoverflow.com/amzn/click/com/1491903996(Scott Meyers)似乎提出了错误的建议,建议像我一样实现 pimpl-idiom move 构造函数Object2
.
[dcl.fct.def.default]/p2:
如果函数在其第一个声明中显式默认,
- 它被隐含地认为是
constexpr
如果隐式声明是,并且,
- 它具有与隐式声明相同的异常规范(15.4)。
如果函数在稍后的声明中显式默认(如后面的示例所示),则这些规则不适用,因此,除了析构函数之外,该函数被视为noexcept(false)
默认情况下,像大多数其他功能一样。
由于显式默认可以在不同的翻译单元中 - 在 pimpl 情况下,is在不同的 TU 中 - 编译器没有通用的方法可以在看到类定义后确定移动构造函数是否会抛出异常,除非该函数在类定义中显式默认(即在其第一次声明时)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)