=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: