9

我相当了解右值引用是如何工作的,但我不确定它们如何与 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 有一个拼接方法。但我想知道这是否可行。它也适用于双端队列吗?

4

2 回答 2

13

splice移动容器的内容是不同的操作。在这种情况下splice(不能用 来完成deque)整个节点从一个容器转移到另一个容器。节点将不再位于原始容器中,并且该操作不会执行任何分配。

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

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

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

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

于 2012-09-27T21:40:09.820 回答
5

你想要std::make_move_iterator()

L.insert(
    insertPoint,
    std::make_move_iterator(R.begin()),
    std::make_move_iterator(R.end())
);
于 2012-09-27T21:26:48.810 回答