std :: vector.push_back(std :: move(foo))是否有意义? [英] Does std::vector.push_back(std::move(foo)) make sense?

查看:399
本文介绍了std :: vector.push_back(std :: move(foo))是否有意义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一些代码中遇到了这个问题(为清楚起见,省去了细节):

I have come across this in some code (details eliminated for clarity):

std::vector<std::vector<int>> foo;
{
    std::vector<int> bar = {42};
    foo.push_back(std::move(bar)); // Hmmm...
} // Indicate `bar` is no longer needed.

std :: move 似乎不必要我,是吗?行为与 foo.push_back(bar); 有什么不同吗?如果该元素代替 int 而不是 pcl :: PointXYZ 是否与我的实际代码一样?

The std::move looks unnecessary to me, but is it? Is the behaviour any different from just foo.push_back(bar);? What if instead of an int the element is a class such as pcl::PointXYZ as it is in my actual code?

UPDATE :我更改了代码,以更明确地指示在 std :: move bar $ c>,因此没有非法访问等风险。

UPDATE: I have altered the code to more explicitly indicate that bar is not used after the std::move, so there is no illegal access, etc, risk.

推荐答案

Class vector 具有两个 push_back 实现:

Class vector has two push_back implementations:

void push_back( const T& value );
void push_back( T&& value );

第一个复制给定元素。

第二个尝试通过调用元素的move构造函数(如果已定义)来移动它。

The second tries to "move" it by calling element's move constructor (if it's defined).

使用 move 强制选择第二个实现,该实现应该重用该值而不是仅复制一个值。

Using move forces to pick the second implementation which is supposed to reuse the value rather than just copying one.

在这种特殊情况下,这将会发生:

In this particular case this is what gonna happen:


  1. 向量 bar 分配在堆栈上,但其元素(42)分配在堆栈上

  2. 调用 foo.push_back(...)时, foo 在堆上分配一个新的向量,该向量将是 bar 的副本。我们称其为 baz :)根据调用哪个 push_back 实现,然后将发生以下情况:


    • void push_back(const T& value); :在这种情况下,所有 bar 的元素也将被复制到 baz

    • void push_back(T& & value); 在这种情况下 baz 将收到指向 bar 的指针元素,因此不执行复制操作。但是了解以下内容至关重要: bar 将被剥夺其元素(现在 baz 拥有它们),因此<$ 移动后不应该使用c $ c> bar 。

  1. Vector bar is allocated on the stack, but its elements (42) are allocated on the heap.
  2. When you call foo.push_back(...), foo allocates on the heap a new vector, which is gonna be bars copy. Let's call it baz :) Depending on which push_back implementation is called the following will happen then:
    • void push_back( const T& value );: in this case all bar's elements will be copyed to baz as well.
    • void push_back( T&& value ); in this case baz will receive a pointer to bar's elements, so no copy operations are performed. But it is crucial for understanding that bar will be deprived of its elemets (now baz owns them), so bar shoun't be used after move.

元素的种类不是很重要(普通整数或 pcl :: PointXYZ ),因为只有第一个向量为元素分配了内存,并且指向该内存的指针是在 move 调用期间唯一复制的内容。

It isn't that important what kind of the elements are (plain ints or pcl::PointXYZ), since only the first vector has allocated the memory for the elements, and the pointer to that memory is the only thing that is copyed during the move call.

这篇关于std :: vector.push_back(std :: move(foo))是否有意义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆