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

Move objects from unordered associative container

本文关键字:移动 对象 无序 关联      更新时间:2023-10-16

c++0x中是否有任何方法可以将对象从无序的关联容器中移出?我需要合并两个独立的无序集合,如果涉及到重新值,我希望在即将停止的集合中"回收"项目。

问题是,unordered_set的迭代器只提供对存储项的常量引用。我最初曾想过使用const_cast来消除constness,但在进一步阅读后,这似乎会导致未定义的行为。有什么建议吗?

编辑

举个简单的例子:

#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中移动项目,而不是复制它们。应该有一种从集合中"提取"项目的方法,即复制/移动项目,然后将其从当前集合中删除。

当前规范中没有这样的功能。但您并不是唯一一个请求它的人。我们可能在未来获得此功能,但前提是像您这样的人对需要它发出了很多噪音。

LWG问题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是否满足您的需求,请私下或在这里询问我,如果可以,我会澄清。

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

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

不能更改集合中的元素(无论是否排序),因为这会破坏唯一性保证。