【问题标题】:Why moving a shared_ptr is allowed in a const_iterator?为什么在 const_iterator 中允许移动 shared_ptr?
【发布时间】: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&lt;&gt; &amp;&amp;std::shared_ptr 没有这样的构造函数,所以最接近的匹配是 shared_ptr( const shared_ptr&amp; r ); - 通常的复制构造函数。
  • 谢谢 dip 和 zch,当 sharedPtrVector 处于未定义状态时,我无法重现测试,所以这可能是我代码中其他地方的错误。它是像你说的那样调用的复制构造函数。
  • 我建议for(auto it=sharedPtrVector.cbegin(); it!=sharedPtrVector.cend(); ++it)
  • @ChrisDrew 如果你想更新这段代码,为什么不for(auto const&amp; e : sharedPtrVector)

标签: c++11 iterator constants shared-ptr move


【解决方案1】:

正如 cmets 中所讨论的,std::move 实际上并不执行移动,它只是将迭代器强制转换为右值引用,以便可以从中移动它。在const std::shared_ptr&lt;T&gt;&amp; 的情况下,它将转换为const std::shared_Ptr&lt;T&gt;&amp;&amp;std::shared_ptr&lt;T&gt; 移动构造函数不接受它,因此它将使用复制构造函数。

这可以通过检查const_iterator指向的shared_ptr&lt;T&gt;之后是否为空来确认:

std::vector<std::shared_ptr<std::string>> sharedPtrVector;

sharedPtrVector.emplace_back(std::make_shared<std::string>("test"));

for (auto it = sharedPtrVector.cbegin(); it != sharedPtrVector.cend(); ++it) {
    std::shared_ptr<std::string> test(std::move(*it));
    if (*it)
        std::cout << "*it is not empty\n";
}

【讨论】:

    猜你喜欢
    • 2017-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 2011-02-24
    • 2010-10-09
    • 2020-04-28
    相关资源
    最近更新 更多