lvalue在函数中作为rvalue(c ++)传递了什么?

时间:2015-05-12 12:49:22

标签: c++ rvalue-reference

我一整天都在想这个问题,但我找不到具体案例的答案。

主要:

std::vector<MyObject*> myVector;
myVector.reserve(5);
myFunction(std::move(myVector));

myFunction:

void myFunction(std::vector<MyObject*> && givenVector){
    std::vector<MyObject*> otherVector = givenVector;
    std::cout << givenVector[0];
    // do some stuff
}

我的问题是:

    在主要的
  1. 中,myVector被函数myFunction()破坏,因为它被认为是一个右值,或者编译器知道它也是一个左值,因此在发送之前执行一个副本它到myFunction?如果我在调用myFunction()之后尝试使用向量会发生什么?

  2. 函数myFunction()内的
  3. 是否受到givenVector影响后被解除的向量otherVector?如果是这样,当我尝试打印时会发生什么?如果不是在这个函数中使用rvalue有用吗?

5 个答案:

答案 0 :(得分:1)

看起来像duplicate

  1. 函数myFunction()不会破坏myVector。没有具体说明在具有stealen资源的类的一般情况下会发生什么。

  2. 当受影响到otherVector时,givenVector不会被销毁。没有具体说明在具有stealen资源的类的一般情况下会发生什么。

答案 1 :(得分:0)

如果函数通过rvalue-reference获取参数,那并不意味着将被破坏性地使用,只是它可以

破坏性使用意味着此后传递的对象处于某种未指定但有效的状态,仅适用于重新初始化,复制,复制或销毁。

在函数中,参数有一个名称,因此是一个左值 要标记您希望利用许可证无情地掠夺它的地方,您必须将其转换为rvalue-reference传递它,例如使用std::movestd::forward ,后者主要用于模板。

答案 2 :(得分:0)

代码不会编译,因为您尝试将左值绑定到 rvalue 引用。您需要故意将其转换为 rvalue

myFunction(std::move(givenVector));

简单地做这件事就不会破坏&#34;物体;会发生什么取决于功能的作用。一般来说,采用 rvalue 引用的函数是为了从参数中移出来的,在这种情况下,它们可能会将它保留在某些有效但是&#34;空的&#34;国家,但不会摧毁它。

您的代码将向量移动到本地otherVector,将其留空。然后尝试打印空向量的第一个元素,给出未定义的行为。

答案 3 :(得分:0)

  1. 不执行复制。 myVector会发生什么情况取决于myFunction对它的作用。您应该将已移动的对象视为相同或为空。您可以指定新值并继续使用或销毁它。

  2. myVector没问题。它是一个左值,otherVector制作它的副本。您最有可能想写otherVector = std::move(myVector);,在这种情况下myVector应为空。如果您有一个旧的STL实现(不知道移动语义),则执行副本并且不更改myVector。如果这是有意义的,你可以决定。您将给定的vector移动到新的vector,这可能很有用。打印空vector并不是那么有用。

答案 4 :(得分:0)

为了进行编译,您应该在向量传递给函数之前应用std::move( - 至少如果不存在进一步的重载):

myFunction(std::move(myVector));

然后,在函数内部,通过

std::vector<MyObject*> otherVector = std::move(givenVector);  

调用std::vector的移动构造函数,它基本上将所有内容移出向量(请注意右侧的std::move - 否则您将获得副本) 。这样,矢量不会被“破坏”。即使在移动之后它仍处于活动状态,但处于未指定的状态。

这意味着可能会调用那些对向量状态没有特定条件的成员函数,例如析构函数,size()运算符等。然而,pop_back()或矢量元素的derefencing可能会失败。

有关移动对象的更多详细说明,请参阅here