问题描述
我在一些代码中遇到了这个问题(为清楚起见,省去了细节):
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
而不是是否与我的实际代码一样?
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 $ c之后不使用
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:
- 向量
bar
分配在堆栈上,但其元素(42)分配在堆栈上 - 调用
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 。
-
- Vector
bar
is allocated on the stack, but its elements (42) are allocated on the heap. - When you call
foo.push_back(...)
,foo
allocates on the heap a new vector, which is gonna bebar
s copy. Let's call itbaz
:) Depending on whichpush_back
implementation is called the following will happen then:void push_back( const T& value );
: in this case allbar
's elements will be copyed tobaz
as well.void push_back( T&& value );
in this casebaz
will receive a pointer tobar
's elements, so no copy operations are performed. But it is crucial for understanding thatbar
will be deprived of its elemets (nowbaz
owns them), sobar
shoun't be used aftermove
.
元素的种类不是很重要(普通整数或 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))是否有意义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!