移动构造函数是否=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)); // prints copy
}
它打印:
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; }
//nonmovable( nonmovable &&) = delete;
};
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
因此,如果您想知道程序中发生了什么,请自己做所有事情:sigh: