一个
=default
的移动构造函数是否等同于按成员逐一移动的移动构造函数?
是的。
更新: 好吧,不总是这样。看看这个例子:
#include <iostream>
struct nonmovable
{
nonmovable() = default;
nonmovable(const nonmovable &) = default;
nonmovable( nonmovable &&) = delete;
};
struct movable
{
movable() = default;
movable(const movable &) { std::cerr << "copy" << std::endl; }
movable( movable &&) { std::cerr << "move" << std::endl; }
};
struct has_nonmovable
{
movable a;
nonmovable b;
has_nonmovable() = default;
has_nonmovable(const has_nonmovable &) = default;
has_nonmovable( has_nonmovable &&) = default;
};
int main()
{
has_nonmovable c;
has_nonmovable d(std::move(c));
}
它会打印出:
copy
http://coliru.stacked-crooked.com/a/62c0a0aaec15b0eb
你声明了默认移动构造函数,但是复制操作代替了移动。为什么?因为如果一个类有至少一个不可移动的成员,则显式默认的移动构造函数会被隐式删除(这真是一个双关语)。因此,当你运行
has_nonmovable d = std::move(c)
时,实际上调用的是复制构造函数,因为
has_nonmovable
的移动构造函数被删除(隐式),它实际上不存在(即使你通过表达式
has_nonmovable(has_nonmovable &&) = default
显式声明了移动构造函数)。
但是,如果
non_movable
的移动构造函数根本没有声明,那么移动构造函数将用于
movable
(以及每个具有移动构造函数的成员),而复制构造函数将用于
nonmovable
(以及每个未定义移动构造函数的成员)。请参见以下示例:
#include <iostream>
struct nonmovable
{
nonmovable() = default;
nonmovable(const nonmovable &) { std::cerr << "nonmovable::copy" << std::endl; }
};
struct movable
{
movable() = default;
movable(const movable &) { std::cerr << "movable::copy" << std::endl; }
movable( movable &&) { std::cerr << "movable::move" << std::endl; }
};
struct has_nonmovable
{
movable a;
nonmovable b;
has_nonmovable() = default;
has_nonmovable(const has_nonmovable &) = default;
has_nonmovable( has_nonmovable &&) = default;
};
int main()
{
has_nonmovable c;
has_nonmovable d(std::move(c));
}
它会打印出:
movable::move
nonmovable::copy
http://coliru.stacked-crooked.com/a/420cc6c80ddac407
更新:但是,如果你注释掉这行代码:has_nonmovable(has_nonmovable &&) = default;
,那么复制将用于两个成员:http://coliru.stacked-crooked.com/a/171fd0ce335327cd - 输出:
movable::copy
nonmovable::copy
所以,在所有地方放置
=default
可能仍然是有意义的。这并不意味着你的移动表达式总是会移动,但这样做可以增加这种可能性。
另外一个更新:但是如果将
has_nonmovable(const has_nonmovable &) = default;
这一行注释掉,结果将会是:
movable::move
nonmovable::copy
所以,如果你想知道程序中发生了什么,就只能自己做一切:叹气: