问题描述
似乎我不能完全理解移动语义:我想从外部函数填充std::vector
(类的成员).目前,我有类似的东西:
It seems that I cannot completely understand move semantics: I want to fill an std::vector
(member of a class) from an external function. Currently, I have something like:
void fillVector(MyClass & myclass) {
std::vector<int> vec;
/* Filling vec */
// ...
myclass.setVector(vec);
}
class MyClass {
public:
setVector(const std::vector<int> & v) { v_ = v;}
private:
std::vector<int> v_;
};
int main() {
MyClass myclass;
fillVector(myclass);
/* Use myclass.v_ somehow */.
}
我已经有很长时间了,并且可以正常工作.现在,我不知道它是如何工作的,因为我要指定一个将被销毁的向量的引用.我的问题是:
I had this code for a long time, and it works fine. Now, I cannot understand how it works since I am asigning a reference to a vector which will be destroyed. My questions are:
- 此代码如何工作?
- 实现
fillVector
和MyClass::setVector()
的最佳方法是什么?我认为可以通过移动语义来完成,但是我不知道怎么做.
- How is this code able to work?
- What is the best way to implement
fillVector
andMyClass::setVector()
? I think that can be done with move semantics but I cannot figure out how.
谢谢!
推荐答案
代码为什么起作用:
vec
的范围是fillVector
的主体.在整个范围内,vec
是完全有效的.这包括对setVector
的调用. v
(setVector
的参数)是绑定到vec
的引用. setVector
的主体将向量vec
(作为v
访问)的内容复制到v_
.那是数据的实际副本,没有引用分配. setVector
结束后,fillVector
结束,此时vec
被销毁.但是它已经被复制了,所以一切都很好.
The scope of vec
is the body of fillVector
. Inside this entire scope, vec
is perfectly valid. This includes the call to setVector
. v
(the parameter of setVector
) is a reference which binds to vec
. The body of setVector
copies the contents of the vector vec
(accessed as v
) into v_
. That's an actual copy of data, no reference assignment. Only after setVector
ends does fillVector
end, at which point vec
is destroyed. But it was already copied, so all is well.
如何使用移动语义:
您可以提供setVector
的额外重载,该重载将使用右值引用:
You could provide an extra overload of setVector
which will take an rvalue reference:
class MyClass {
public:
// ...
void setVector(std::vector<int> &&v) { v_ = std::move(v); }
// ...
};
然后,移动 vec
到setVector
:
void fillVector(MyClass & myclass) {
std::vector<int> vec;
/* Filling vec */
// ...
myclass.setVector(std::move(vec));
}
这将调用右值重载而不是左值重载,并且数据将被移动而不是复制.
This will invoke the rvalue overload instead of the lvalue one, and the data will be moved, not copied.
但是,也许更好的接口是重构fillVector
,以便它自动使用移动语义按值返回向量:
However, perhaps a better interface would be to refactor fillVector
so that it returns the vector by value, using move semantics automatically:
std::vector<int> fillVector() {
std::vector<int> vec;
/* Filling vec */
// ...
return vec; // Note that a move automatically happens here, or even NRVO
}
int main() {
MyClass myclass;
myclass.setVector(fillVector());
/* Use myclass.v_ somehow */.
}
这篇关于如何改善std :: vector参数传递(移动语义?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!