在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;来自集合的项目,以便复制/移动项目,然后从当前集合中删除。
答案 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中的元素(已订购或未订购),因为这会破坏唯一性保证。