基本上,我想要一个容器,其中一个元素可以被许多键访问。这可以通过定义一些用作地图键类型的多键类来完成,但由于这样的解决方案不允许修改已经插入的元素的键,我无法为其创建新的别名现有条目。
我很欣赏std::map
密钥需要为了排序而保持不变,但为什么std::unordered_map
存在此限制?
如果需要,我想我可以使用指针图,但是有更好,更优雅的解决方案吗?
编辑:感谢清除Andrei,Xeo。尼科尔,关于我应该使用什么容器的任何建议?
答案 0 :(得分:8)
嗯,std::unordered_map
不允许你修改密钥的原因与其他关联容器不允许你修改它的原因几乎相同:它会弄乱数据的内部组织结构体。
在unordered_map
中,密钥用于获取散列,并且该散列告诉容器放置元素的容器(当然是从哪个存储桶中检索它)。如果修改密钥,则修改哈希值,这意味着应将元素移动到其他存储桶。这就像删除它并再次插入它一样。
另一方面,关联容器的整体思想是任何元素都由一个固定的值表示,这样它在容器中的位置可以作为该值的函数快速计算。如果允许多个密钥,您可以使用哪个密钥快速确定元素的存储位置或存储位置?
您想要的可能是 ad-hoc 数据结构,其复杂性保证与标准库不同。
但就个人而言,在我看来,您只是在寻找引用语义,因为您打算共享一个对象的多个视图。这自然会引导我使用(智能)指针,特别是当我听到世界“别名”时。我建议你去找一张shared_ptr
s作为价值的地图。
答案 1 :(得分:2)
在关联容器(例如map
,unordered_map
)中,key
的值确定元素在数据结构中的位置。在非多关联容器中,键也必须是唯一的。
如果允许修改key
,则会危及上述设计不变量。
在map
中,元素在二叉搜索树中的位置
在unordered_map
中,将元素链接到哈希桶
如果我理解OP的要求,那么可以通过在容器的insert()
上写一个包装器来实现,例如下面的C ++ - ish伪代码:
Iterator insert_wrapper( Container & cont, Element const & elem ) {
if elem in cont {
cont.erase( elem );
}
return cont.insert( elem );
}
答案 2 :(得分:1)
你会找到比指针图更有品位的参考图吗?
int value = 6;
std::unordered_map<int, int&> m;
for(int i=0; i<5; ++i)
m.emplace(i, value);
value = 4;
for(auto const& i: m)
std::cout<<i.second<<' ';
当然,您必须将实际值存储在其他位置,如示例所示。