繁体   English   中英

传递给函数的右值以右值(c ++)会发生什么?

[英]what happens to lvalue passed in function as rvalue (c++)?

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

主要:

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. myVectormyVector被函数myFunction()销毁,因为它被视为右值,或者编译器是否知道它也是左值,因此在将其发送到myFunction之前执行了复制操作? 如果在调用myFunction()之后尝试使用向量,会发生什么情况?

  2. 在函数myFunction() ,给定vector受到otherVector影响givenVector被破坏? 如果是这样,当我尝试打印时会发生什么? 如果不是,在此函数中使用rvalue是否有用?

看起来像重复的

  1. myVector不会被函数myFunction()破坏。 对于资源被盗用的类,一般情况下应该发生的情况尚不确定。

  2. 给定Vector受到otherVector影响时不会被破坏。 对于资源被盗用的类,一般情况下应该发生的情况尚不确定。

如果函数通过右值引用获取参数,这并不意味着它将破坏性地使用,而仅仅是可以使用

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

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

该代码将无法编译,因为您尝试将左值绑定到右值引用。 您需要将其故意转换为右值

myFunction(std::move(givenVector));

只需这样做就不会“破坏”对象。 发生什么情况取决于函数的功能。 通常,采用右值引用的函数这样做是为了从参数中移出,在这种情况下,它们可能会将其置于某些有效但为“空”的状态,但不会破坏它。

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

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

  2. myVector很好。 它是一个左值, otherVector复制它。 您最有可能想要编写otherVector = std::move(myVector); ,则myVector应该为空。 如果您有STL的旧实现(不了解移动语义),则会执行复制,并且myVector不会更改。 如果这有意义,则由您决定。 您将给定的vector移到了一个新的vector ,这可能会很有用。 打印空vector不是那么有用。

为了可编译,应在将其传递给函数之前将std::move应用于向量(至少在不存在其他重载的情况下):

myFunction(std::move(myVector));

然后,在函数内部,通过

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

将调用std::vector的move构造函数,该方法将所有内容从向量中移出(但是请再次注意,将std::move右侧-否则将获得一个副本)。 由此,载体没有被“破坏”。 即使在移动之后,它仍然存在,但处于未知状态。

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

请参阅此处以获得更详细的解释,您仍然可以对移出的对象进行处理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM