我一整天都在想这个问题,但我找不到具体案例的答案。
主要:
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
被函数myFunction()
破坏,因为它被认为是一个右值,或者编译器知道它也是一个左值,因此在发送之前执行一个副本它到myFunction
?如果我在调用myFunction()
之后尝试使用向量会发生什么?
myFunction()
内的是否受到givenVector
影响后被解除的向量otherVector
?如果是这样,当我尝试打印时会发生什么?如果不是在这个函数中使用rvalue有用吗?
答案 0 :(得分:1)
看起来像duplicate。
函数myFunction()不会破坏myVector。没有具体说明在具有stealen资源的类的一般情况下会发生什么。
当受影响到otherVector时,givenVector不会被销毁。没有具体说明在具有stealen资源的类的一般情况下会发生什么。
答案 1 :(得分:0)
如果函数通过rvalue-reference获取参数,那并不意味着将被破坏性地使用,只是它可以。
破坏性使用意味着此后传递的对象处于某种未指定但有效的状态,仅适用于重新初始化,复制,复制或销毁。
在函数中,参数有一个名称,因此是一个左值
要标记您希望利用许可证无情地掠夺它的地方,您必须将其转换为rvalue-reference传递它,例如使用std::move
或std::forward
,后者主要用于模板。
答案 2 :(得分:0)
代码不会编译,因为您尝试将左值绑定到 rvalue 引用。您需要故意将其转换为 rvalue :
myFunction(std::move(givenVector));
简单地做这件事就不会破坏&#34;物体;会发生什么取决于功能的作用。一般来说,采用 rvalue 引用的函数是为了从参数中移出来的,在这种情况下,它们可能会将它保留在某些有效但是&#34;空的&#34;国家,但不会摧毁它。
您的代码将向量移动到本地otherVector
,将其留空。然后尝试打印空向量的第一个元素,给出未定义的行为。
答案 3 :(得分:0)
不执行复制。 myVector
会发生什么情况取决于myFunction
对它的作用。您应该将已移动的对象视为相同或为空。您可以指定新值并继续使用或销毁它。
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。