class C
{
public:
C(C&&) = default; // (1)
C& operator=(C&&) = default; // (1)
C(C&&) noexcept = default; // (2)
C& operator=(C&&) noexcept = default; // (2)
}
据我所知,如果移动构造函数/赋值运算符是由用户隐式生成或显式默认的
(1)
,编译器将根据 a 的所有成员是否都决定这些特殊成员函数是否应该为 noexcept
类为移动操作提供noexcept
保证。但是,如果我想使用默认的移动特殊成员并强制它们为 noexcept
,而不管移动操作的底层成员异常保证如何,该怎么办? (1)
和 (2)
声明对于编译器来说有什么区别吗?
好吧,我在 Nico 的 Josuttis 书《C++ Move Semantics - The Complete Guide》中找到了答案:
当您有默认的特殊成员函数时,您可以显式指定与生成的不同的 noexcept 保证。例如:
class C
{
...
public:
C(const C&) noexcept = default; // guarantees not to throw (OK since C++20)
C(C&&) noexcept(false) = default; // specifies that it might throw (OK since C++20)
...
};
C++20之前,如果生成的noexcept条件与指定的noexcept条件矛盾,则定义的函数被删除。