【发布时间】:2014-03-01 09:01:30
【问题描述】:
using Ptr = std::unique_ptr<int>;
Ptr f(bool arg) {
std::list<Ptr> list;
Ptr ptr(new int(1));
list.push_back(std::move(ptr));
if (arg) {
Ptr&& obj1 = std::move(list.front());
// Here |obj1| and |list.front()| still point to the same location!
list.pop_front();
return std::move(obj1);
}
else {
Ptr obj2 = std::move(list.front());
list.pop_front();
return obj2;
}
};
Ptr&& ptr1 = f(true); // |ptr1| is empty.
Ptr&& ptr2 = f(false); // |ptr2| is fine.
完整来源是here。
我不明白——为什么obj1 和list.front() 在调用std::move() 之后仍然指向同一个位置?
【问题讨论】:
-
你为什么使用这么多的右值引用?如果你使用
Ptr obj1 =而不是Ptr&& obj1 =,一切都应该没问题。 -
@nosid 我有一个模糊的解释。我正在尝试使用 libc++ 中的
std::experimental::optional- 而不是Ptr。我的optional包含成对的unique_ptrs 和仅移动对象(即没有默认 ctor)。变体Ptr obj2 =甚至无法编译 - 但Ptr&& obj1 =可以。然后我对我在问题中解释的情况感到惊讶。当然,我应该检查optional本身的问题,但先弄清楚最简单的事情会更容易。 -
单独考虑表达式
std::move(list.front())。如果std::move确实移动了它的参数(提示:它没有),那么该对象究竟会被移动到哪里到? -
@FredOverflow 我的猜测 - 在正常情况下,它应该移动到临时对象,如
Ptr(),当离开范围时会被销毁。但是由于右值引用 - 它应该留得更长一点。 -
其实,你的猜测听起来不无道理,但事实并非如此。
标签: c++ c++11 move-semantics unique-ptr rvalue-reference