unique_ptr在移动后保证存储nullptr吗?

85

unique_ptr在移动后是否保证存储nullptr?

std::unique_ptr<int> p1{new int{23}};
std::unique_ptr<int> p2{std::move(p1)};
assert(!p1); // is this always true?

2
从技术上讲,::move 离开元素的状态是未指定的。我认为智能指针也没有任何保证。话虽如此,我会留给 CPP 专家来回答 :) - Benjamin Gruenbaum
1
等等,不对,是的。释放显式地将其设置为nullptr。这是由unique_ptr保证的。 - Benjamin Gruenbaum
gcc 4.8.1在此,std::move后p1为空。 - Exceptyon
1
请参阅std::unique_ptr::operator:std::unique_ptr::release的任何参考资料。 - rubenvb
只需看一下移动语义... - Deduplicator
显示剩余2条评论
2个回答

76

是的,在move之后,您可以将其与nullptr进行比较,并且保证它们相等。

来源于§20.8.1/4 [unique.ptr]

此外,u可以在请求时将所有权转移给另一个唯一指针u2。完成此类转移后,会满足以下后置条件:
u2.p等于转移前的u.p,
u.p等于nullptr,并且
...

(成员p早些描述为—一个唯一指针是存储对第二个对象p的指针的对象u


在调用release()之后,这显然是正确的。但是std::move不会调用release()。那么编译器如何知道恢复unique_ptr的不变量呢? - mabraham
1
@mabraham p2{std::move(p1)} 是将 p1 移动构造到 p2。这就是我在引用的文本中所说的所有权转移请求。移动构造函数的实现将确保满足所有后置条件。 - Praetorian
谢谢。重新表述:使用移动构造函数请求所有权转移,必须保持p1的不变性。std::move只是使移动构造函数可用。 - mabraham

11

是的。来自C++2011标准第20.7.1/4节:

此外,您可以根据要求将所有权转移给另一个唯一指针u2。完成此类转移后,以下后置条件成立[源唯一指针]等于nullptr...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接