这是我获取大部分信息的地方:http://en.cppreference.com/w/cpp/language/move_constructor
显然这些是隐式生成的移动构造函数的工作条件:
default
我的问题是:
我更倾向于遵循三个规则并手动创建一个析构函数,一个复制和移动构造函数,以及一个复制和移动赋值运算符,但我只是好奇这个隐含一个。
答案 0 :(得分:5)
以下是您的问题的答案:
答案 1 :(得分:3)
1
。依赖隐式自动移动构造函数是否安全?
没有测试(隐式或显式),没有什么是安全的。
2
。如何检查它是否真的有效而不是默认的复制构造函数?
测试。请参阅下面的示例测试。
3
。最后,最重要的是,这是一个好主意,为什么?或者是它 总是更好地定义自己的?
使您的特殊成员琐碎具有明显(且不断增长)的优势。一个普通的特殊成员是由编译器定义/提供的成员。您可以使用= default
声明一个简单的成员。实际上,最后一句话是夸张的。如果您使用= default
声明特殊成员,那么肯定不会是微不足道的。这取决于你的成员和基地。但是如果你明确地定义一个特殊的成员(如在C ++ 98/03中),那么肯定它不会是微不足道的。如果您可以选择用户提供的和琐事,请选择琐碎。
此外,您无需测试类型X
是否具有移动构造函数。如果您移动构造您的X
,则需要测试它是否具有正确的异常安全性和正确的性能。如果X::X(const X&)
完成了那项任务,那就这样吧。在这种情况下,X::X(X&&)
不是必需的。
如果您希望类型X
具有投掷副本构造函数和更快noexcept
移动构造函数,那么这是一个非常好的测试来确认它是这样的:
static_assert(std::is_nothrow_move_constructible<X>::value,
"X should move construct without an exception");
将此测试放在源/标题中。现在,无论您是隐式地,还是明确地声明或定义您的特殊成员,您都有一个具体的编译时测试,几乎是零成本。 static_assert
生成零代码,并且消耗的编译时间可以忽略不计。