[英]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
}
我的问题是:
myVector
, myVector
被函数myFunction()
销毁,因为它被视为右值,或者编译器是否知道它也是左值,因此在将其发送到myFunction
之前执行了复制操作? 如果在调用myFunction()
之后尝试使用向量,会发生什么情况?
在函数myFunction()
,给定vector受到otherVector
影响givenVector
被破坏? 如果是这样,当我尝试打印时会发生什么? 如果不是,在此函数中使用rvalue是否有用?
看起来像重复的 。
myVector不会被函数myFunction()破坏。 对于资源被盗用的类,一般情况下应该发生的情况尚不确定。
给定Vector受到otherVector影响时不会被破坏。 对于资源被盗用的类,一般情况下应该发生的情况尚不确定。
如果函数通过右值引用获取参数,这并不意味着它将被破坏性地使用,而仅仅是可以使用 。
破坏性使用意味着此后传递的对象处于某种未指定但有效的状态,仅适合于重新初始化,移动,复制或销毁。
在函数中,参数具有名称,因此是左值。
要标记您想利用许可证无情掠夺的地方,您必须在传递时将其转换为右值引用,例如使用std::move
或std::forward
,后者主要用于模板。
该代码将无法编译,因为您尝试将左值绑定到右值引用。 您需要将其故意转换为右值 :
myFunction(std::move(givenVector));
只需这样做就不会“破坏”对象。 发生什么情况取决于函数的功能。 通常,采用右值引用的函数这样做是为了从参数中移出,在这种情况下,它们可能会将其置于某些有效但为“空”的状态,但不会破坏它。
您的代码将向量移动到本地otherVector
,将其留空。 然后,您尝试打印空向量的第一个元素,给出未定义的行为。
不执行复制。 myVector
会发生什么情况取决于myFunction
对其执行的操作。 您应该将已从移走的对象视为相同或为空。 您可以分配新值并继续使用或销毁它。
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.