【问题标题】:std::move items out of an STL container?std::move 项目出 STL 容器?
【发布时间】:2016-11-04 01:41:12
【问题描述】:

我正在尝试从std::set 中删除一个元素std::move,然后将其从集合中删除:

std::set<some_type> the_set;
some_type item;   

for (auto iter = the_set.begin(); iter != the_set.end(); iter++)
{
    auto miter = std::make_move_iterator(iter);
    item = std::move(*miter);
    the_set.erase(iter);
    break;
}

但编译器不喜欢它(MSVC 2015):

error C2280: 'some_type &some_type::operator =(const some_type &)': attempting to reference a deleted function

似乎它正在尝试使用复制构造函数,这是我不想要的。我如何让它使用移动构造函数? (我绝望地尝试了move_iterator,不确定这是否是正确的解决方案)。

【问题讨论】:

    标签: c++ c++11 std move-semantics


    【解决方案1】:

    std::set 迭代器实际上是 const 迭代器(在 C++11 和更高版本中)。这样一来,您就不可能更改它们并破坏set 的顺序。

    而且您不能从const&amp;&amp; 移动。所以你不能搬出set

    C++17 将允许您这样做,但 via a different API (PDF)。基本上,你必须extract the node itself from the set,然后移动节点中的对象,然后销毁节点(通过让它从堆栈中掉下来)。我相信代码看起来像这样:

    for (auto iter = the_set.begin(); iter != the_set.end(); iter++)
    {
        auto node = the_set.extract(iter);
        item = std::move(node.value());
        break;
    }
    

    【讨论】:

    • 因为在我的情况下我在移动后立即删除,我可以使用 const cast 来完成移动吗?我知道这可能有点 hacky...
    • @atanamir:可能不会。当您将 move 取出时(实际上某些东西会改变其内容以交换数据),set 处于不一致状态(排序不变量可能已损坏)。它用于删除项目的算法依赖于这个不变量(哎呀,它们依赖于对象处于可用状态,用于诸如operator&lt; 调用之类的东西,并且在你搬出某物后得到的唯一保证是可以重新分配或销毁它,不允许其他任何事情;它可能有 NULL 否则非法的指针)。不要尝试这样做。
    • @atanamir:也就是说,看起来 C++17 正在引入 std::set::extract,这将允许您尝试做的事情(假设我没看错)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-30
    • 2012-03-17
    • 2013-03-24
    • 1970-01-01
    • 2016-12-19
    • 2015-03-28
    • 1970-01-01
    相关资源
    最近更新 更多