为什么 multimap 允许重复的键值对?
编辑: 请注意,我不是问为什么多重映射不能包含重复的键。
multimap 允许重复的键值对背后的基本原理是什么? (不是键)
#include <map>
#include <string>
#include <iostream>
int
main(int argc, char** argv)
{
std::multimap<std::string, std::string> m;
m.insert(std::make_pair("A", "B"));
m.insert(std::make_pair("A", "B"));
m.insert(std::make_pair("A", "C"));
std::cout << m.size() << std::endl;
return 0;
}
这个打印的3,这让我有点惊讶,我期望多重映射的行为就像一组对,所以我期待2。
直观上,它与C++ std::map
行为,其中 insert
并不总是更改映射(与 operator[]
相反)。
其背后是否有其合理性,或者只是任意的?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
Multimap 只有一个对键进行排序的谓词。它没有方法确定值是否相等。值“A”是否与值“a”重复?如果没有值的第二个谓词,就无从得知。因此,谈论多重映射中的重复值甚至没有意义。
如果您想要一个存储对的容器,并强制该对的两个部分的唯一性,请查看
boost::multi_index_container
。它非常灵活,但因此需要大量参数。Multimap only has a predicate ordering the keys. It has no method to determine whether the values are equal. Is value "A" a duplicate of value "a"? Without a second predicate for the values, there's no telling. Therefore, it doesn't even make sense to talk about duplicate values in a multimap.
If you would like a container that stores pairs, and enforces the unique-ness of both parts of the pair, look at
boost::multi_index_container
. It's very flexible, but takes a load of arguments as a result.编辑:这个答案不再回答当前的问题。我会保持原样,因为它得到了很多支持,所以它对某些人来说一定有用。
multimap
中的multi 代表同一个键可以出现多次 次。该标准对用作值的类型没有限制,因此不能假设定义了
operator==()
。因为我们不希望代码的结果取决于是否定义了operator==(),所以永远不会使用它。std::multimap
不能替代std::map
。正如您所注意到的,当多次插入相同的密钥时,它的行为会有所不同。如果您想要std::map
的行为,请使用std::map
。还有一个
std::multiset
。理由是:有时人们也希望保留同一密钥的所有旧条目。 [TBD:在此插入一些示例]
就我个人而言,我几乎从未使用过
std::multimap
。如果我想要同一个键有多个条目,我通常依赖std::map >
。EDIT: This answer does not answer the current question anymore. I'll keep it as it is because it got upvoted a lot so it must be useful for some.
The multi in
multimap
stands for the fact that the same key can occur multiple times.The standard puts no limit on the type used as value, so one cannot assume that
operator==()
is defined. Because we don't want the result of your code depend on whether the operator==() is defined or not, it is never used.std::multimap
is not a replacement forstd::map
. As you noticed, it behaves differently when the same key is inserted multiple times. If you wantstd::map
's behaviour, usestd::map
.There is also a
std::multiset
.The rational: sometimes one would like to keep all old entries for the same key around as well. [TBD: Insert some example here]
Personally, I barely ever use
std::multimap
. If I want multiple entries for the same key, I usually rely onstd::map<std::vector<T> >
.这些值允许重复,因为它们不需要相互比较。除了将值复制进来之外,容器不能对这些值执行任何操作。这使得诸如
multimap<; 之类的类型成为可能。 int,my_class>
。如果不希望出现重复的键值对,请使用
set<对< T、U> >
并使用lower_bound
查找给定键的第一个匹配项。The values are allowed to be duplicates because they are not required to be comparable to each other. The container cannot do anything with the values besides copy them in. This enables types like
multimap< int, my_class >
.If duplicate key-value pairs are undesirable, then use
set< pair< T, U > >
and uselower_bound
to find the first match to a given key.如您所知,
multimap
允许拥有多个键。由于它不对值的可比性施加任何限制,因此无法检查值是否未加倍。如果您想要某种允许重复键但不允许键值对的字典数据结构,则必须确保值是可比较的。
假设我们有某种游戏,其中有正方形字段的 2D 世界,并且您可以将物品放在字段上。您可以使用
multimap
,这将允许您在字段上保留两个相同的项目。此处的项目不必具有可比性。As you know,
multimap
allows to have multiple keys. Since it does not place any constraints on values comparability, it is unable to check, if values haven't been doubled.If you want to have some dictionary data structure which allows for duplicate keys, but not key-value pairs, you would have to ensure that values are comparable.
Let's say we have a game of some sort, where there is 2D world of sqaure fields, and you can put items on fields. You can have
multimap<Field, Item>
, which will allow you to keep two identical items on the field. Items don't have to be comparable here.我的推理是多重映射基于键查找/插入而不是值。因此,在插入元素时,重复键上的值是否相同并不重要。
23.3.2 类模板多重映射
My reasoning is multimap is based on the Key lookup/insertion and not on the value. So whether the value on duplicate keys is the same or not does not play a part when elements are being inserted.
23.3.2 Class template multimap
"multimap" 旨在支持“多个”键,与简单的 "地图"。由于它允许多个键,因此不会打扰它们的值,因此它在您的示例中显示了 3 个元素。另一个区别是,
multimap
不能有operator []
。"multimap" is meant to support 'multiple' keys unlike simple "map". Since it allows multiple keys, it won't bother for their values, so it shows 3 elements in your example. The other difference is, one can not have
operator []
formultimap
.重复的 [map,value] 对的用途是计算某个单词在一本书的一页上出现的次数,无论是否出现次数,因此多重映射中没有该单词的条目,无论是一次还是一个条目,或者多次使用 make_pair(word, page_number) 的 multimap 中出现的次数。我发现这种用法更多的是偶然的设计。
A use of duplicate [map,value] pairs is to count the number of occurrences of say a word on a page of a book, be it no times, thus no entry in the multimap for that word, be it once with one entry, or more than once with the number of occurrences in multimap for make_pair(word, page_number). It was more by accident that design that I found this usage.