按值传递,然后移动,实际上是一个适用于可移动对象的好习惯。
正如您所提到的,如果传递了 rvalue,则它将省略复制或被移动,然后在构造函数内部它将被移动。
您可以显式重载复制构造函数和移动构造函数,但是如果有多个参数,则会变得更加复杂。
考虑以下示例:
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
在一个const&
上会返回一个const&&
,不能从中移动。 - Casey