按值传递,然后移动实际上是您知道可移动对象的一个好习惯。
如您所提到的,如果传递了一个右值,它将取消副本或将其移动,然后在构造函数中将其移动。
您可以重载复制构造函数并显式移动构造函数,但是如果您拥有多个参数,它将变得更加复杂。
考虑这个例子,
class Obj {
public:
Obj(std::vector<int> x, std::vector<int> y)
: X(std::move(x)), Y(std::move(y)) {}
private:
std::vector<int> X, Y;
};
假设如果要提供显式版本,则最终会得到以下4个构造函数:
class Obj {
public:
Obj(std::vector<int> &&x, std::vector<int> &&y)
: X(std::move(x)), Y(std::move(y)) {}
Obj(std::vector<int> &&x, const std::vector<int> &y)
: X(std::move(x)), Y(y) {}
Obj(const std::vector<int> &x, std::vector<int> &&y)
: X(x), Y(std::move(y)) {}
Obj(const std::vector<int> &x, const std::vector<int> &y)
: X(x), Y(y) {}
private:
std::vector<int> X, Y;
};
如您所见,随着参数数量的增加,排列所需的构造函数的数量也会增加。
如果您没有具体的类型,但是有一个模板化的构造函数,则可以像下面这样使用完善转发:
class Obj {
public:
template <typename T, typename U>
Obj(T &&x, U &&y)
: X(std::forward<T>(x)), Y(std::forward<U>(y)) {}
private:
std::vector<int> X, Y;
};
参考文献:
- 要速度吗?价值传递
- C ++调味料
std::move
a会const&
传回const&&
无法移走的a。