【发布时间】:2014-12-07 06:03:50
【问题描述】:
移动 shared_ptr 会将移动的 shared_ptr 设置为 nullptr 那么为什么允许在 const_iterator 中执行此操作?
std::vector<std::shared_ptr<std::string>> sharedPtrVector;
sharedPtrVector.push_back(std::shared_ptr<std::string>(new std::string("test")));
for (std::vector<std::shared_ptr<std::string>>::const_iterator it = sharedPtrVector.begin(); it != sharedPtrVector.end(); ++it) {
// Not allowed if const_iterator
//*it = nullptr;
// Not allowed if const_iterator
//*static_cast<std::shared_ptr<std::string> *>(&*it) = nullptr;
// Allowed even if const_iterator
std::shared_ptr<std::string> test(std::move(*it));
}
此后sharedPtrVector处于未定义状态。
【问题讨论】:
-
std::move不移动,也不强制移动。它宁愿允许从左值移动。是否发生实际的移动操作取决于操作数的 cv 限定(类型)、目标类型的构造函数。在这种情况下,我认为test的构造复制了shared_ptr。 -
我认为在这种情况下
std::move返回const std::shared_ptr<> &&。std::shared_ptr没有这样的构造函数,所以最接近的匹配是shared_ptr( const shared_ptr& r );- 通常的复制构造函数。 -
谢谢 dip 和 zch,当 sharedPtrVector 处于未定义状态时,我无法重现测试,所以这可能是我代码中其他地方的错误。它是像你说的那样调用的复制构造函数。
-
我建议
for(auto it=sharedPtrVector.cbegin(); it!=sharedPtrVector.cend(); ++it) -
@ChrisDrew 如果你想更新这段代码,为什么不
for(auto const& e : sharedPtrVector)?
标签: c++11 iterator constants shared-ptr move