从无序的关联容器中移动对象

时间:2011-05-30 21:46:13

标签: c++ c++11

在c ++ 0x中有没有办法从无序的关联容器中移出对象?我需要合并两个单独的无序集合,如果涉及到rvalues,我想要“回收”。即将停止的项目。

事实上,unordered_set的迭代器只提供对存储项的const引用。我原本以为使用const_cast来抛弃常量,但是进一步阅读它似乎会导致未定义的行为。有什么建议吗?

修改

采取这个简单的例子:

#include <string>
#include <unordered_set>

using namespace std;

void merge_sets(unordered_set<string> &s1, unordered_set<string> &&s2)
{
   // Something like this, which (of course) does not work.
   for (auto it = s2.begin(); it != s2.end(); ++it) {
     s1.insert(std::move(*it));
   }
}

int main()
{
   unordered_set<string> s1, s2;
   // Fill first set:
   s1.insert("hello");
   s1.insert("world");
   // Fill second set.
   s2.insert("foo");
   merge_sets(s1,std::move(s2));
   // After this operation, s2 is empty and s1 contains "hello", "world" and "foo".
}

换句话说,我希望能够从s2移动项目而不是复制它们。应该有一种方法来提取&#34;来自集合的项目,以便复制/移动项目,然后从当前集合中删除。

3 个答案:

答案 0 :(得分:6)

目前的规格中没有这样的功能。但你并不是唯一一个要求它的人。我们可能会在将来获得此功能,但前提是像您这样的人在需要时会产生很多噪音。

LWG issue 839的评论标记为“[2009-09-19 Howard添加:]”,其中描述了将节点从一个基于节点的容器拼接到另一个容器的API。使用您的代码看起来像:

void merge_sets(unordered_set<string> &s1, unordered_set<string> &&s2)
{
   // Something like this, which (of course) does not work.
   for (auto it = s2.begin(); it != s2.end();) {
     s1.insert(s2.remove(it++));
   }
}

这不会涉及任何内存分配或释放。它甚至不需要移动或复制元素。它实际上将节点从一个unordered_set<string>传递给另一个节点。

告诉您的国家机构代表您需要此功能。告诉comp.std.c ++你需要这个功能。如果您不确定此API是否符合您的需求,请私下或在此问我,如果可以,我会澄清。

答案 1 :(得分:1)

为什么不使用其中一个作为目标来合并这两个集合,而不是将它们合并到第三个单独的集合中?这至少可以让你避免从其中一个源集复制元素(可能你会选择较大的元素)。

或者,如果元素很大,你应该使用智能指针间接存储它们(例如boost::shared_ptr<>),在这种情况下,很容易将指针从两个源复制到目标,并且永远不会复制实际对象。

答案 2 :(得分:0)

您无法更改Set中的元素(已订购或未订购),因为这会破坏唯一性保证。