【问题标题】:c++11 move insertion for std::deque or std::listc++11为std::deque或std::list移动​​插入
【发布时间】:2012-09-19 18:17:17
【问题描述】:

我相当了解右值引用的工作原理,但我不确定它们如何与 STL 中的迭代器一起工作。这是我想要的东西:

void insertList(std::list<int>& L, std::list<int>&& R, std::list<int>::iterator insertPoint)
{
    L.insert(insertPoint, R.begin(), R.end()); // want to use move semantics
}

现在我知道 std::list 有一个拼接方法。但我想知道这是否可行。它也适用于双端队列吗?

【问题讨论】:

  • 投票重新开放。虽然有一部分与标记为重复的问题共享(移动到deque),但也有一部分与list&lt;&gt; 非常不同,并且链接问题中的解决方案比替代方案更差@ 987654324@

标签: c++ c++11 rvalue-reference move-semantics


【解决方案1】:

splice移动容器的内容是不同的操作。在splice 的情况下(deque 无法做到这一点),整个节点从一个容器转移到另一个容器。节点将不再位于原始容器中,操作不会执行任何分配。

move 内容的替代方法,使用类似于您所说的算法,但使用 move 迭代器:

L.insert(insertPoint, 
         std::make_move_iterator(R.begin()), 
         std::make_move_iterator(R.end()));

这对listdeque 都有效,但语义不同。插入新列表将需要分配std::distance(R.begin(),R.end()) 节点,其内容将通过从原始容器移动来填充。这降低了创建新节点的成本,但仍然需要分配它们。请注意,旧列表仍将包含所有节点,尽管它们将是 empty,因为数据的内容已被移动。

对于std::list,您应该更喜欢splice,但这在其他容器上不可用。对于其他容器,您将使用上述方法,其中必须承担构建容器数据结构的成本,但可以避免创建存储数据的成本。

【讨论】:

    【解决方案2】:

    你想要std::make_move_iterator():

    L.insert(
        insertPoint,
        std::make_move_iterator(R.begin()),
        std::make_move_iterator(R.end())
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-14
      • 2018-05-31
      • 1970-01-01
      • 1970-01-01
      • 2017-10-17
      • 1970-01-01
      • 2011-02-08
      • 2015-04-01
      相关资源
      最近更新 更多