如何改善std :: vector参数传递(移动语义?) [英] How to improve std::vector parameter passing (move semantics?)

查看:84
本文介绍了如何改善std :: vector参数传递(移动语义?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎我不能完全理解移动语义:我想从外部函数填充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:

  1. 此代码如何工作?
  2. 实现fillVectorMyClass::setVector()的最佳方法是什么?我认为可以通过移动语义来完成,但是我不知道怎么做.
  1. How is this code able to work?
  2. What is the best way to implement fillVector and MyClass::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); }
  // ...
};

然后,移动 vecsetVector:

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参数传递(移动语义?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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