传递可移动对象
Passing a movable object
在SO中阅读答案时,他通过了move
的vector
。我认为正确的方法是在不使用move
的情况下简单传递它:
class B
{
std::vector<T> data;
public:
B(std::vector<T> p) : data(std::move(p)) {}
^^^^^^^^^^^^
?
};
第二种方式是:
class B
{
std::vector<T> data;
public:
B(std::vector<T> p) : data(p) {}
};
哪一个是正确的?
函数参数已经按值获取,因此已经制作了一个副本。本地对象p
毫无疑问是你的,而且只有你自己,所以你可以无条件地离开它。
按值获取参数的美妙之处在于它适用于左值和右值:对于左值,你制作一个真正的副本,因为你无能为力,但对于右值,函数参数本身可以通过移动来构造,所以只有一个昂贵的构造发生,其他一切都被移动。
当您从左值构造对象时,它将被复制。当您从非const
右值构造对象时,可以移动它(是否移动取决于具有移动构造函数的类)。在构造函数的上下文中,p
显然是一个左值:它有一个名称。但是,它是一个局部变量并且即将消失,即保存它以从它移动:std::move(p)
使对象看起来好像是一个右值:在这种情况下,std::move()
值是正确的方法。
请注意,如果返回对象,建议会有所不同:return
语句中返回的本地值会自动移出。使用std::move()
只会加强语句,但也会抑制完全省略复制/移动的可能性。在构造函数中,无法省略复制/移动,因为复制省略仅适用于临时对象或return
语句中的本地对象。
T f() {
T local;
return local; // good: elided, moved, or copied in this order of preference
}
T g() {
T local;
return std::move(local); // bad: can't be elided and will be moved or copied
}
相关文章:
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- 为什么协程的返回类型必须是可移动构造的?
- 我应该使我的局部变量常量还是可移动的
- 对于参加可复制和可移动类的访问者来说,应该有多少过载?
- 如何获取类型是否真正可移动可构造
- 可移动但不可复制的对象:按值传递还是按引用传递?
- 对于可移动类型,按值传递比重载函数更好吗?
- 使用参数将仅可移动对象捕获到 lambda
- 从从可调用参数创建的线程对象参数移动构造 C++11 线程
- C++11/VS2010:返回包含不可复制但可移动对象的容器
- 传递可移动对象
- 无法将可移动对象与Boost.Asio一起使用
- 如何按值返回一个不可复制的、可移动的对象作为const并存储它
- 在std::函数中存储不可复制但可移动的对象
- 在std::pair中存储不可复制(但可移动)的对象
- Boost序列化不可复制但可移动的对象
- 包含boost::可选对象的std::矢量对象是否可以移动?可移动助推::可选
- 编译器是否在最后一次使用可移动对象时自动使用移动语义?
- 外部模板类std::可移动对象的容器
- 作用于可移动但不可复制对象序列的变化STL算法的行为