编辑: 请注意,我不询问为什么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,有点让我感到惊讶,我希望multimap表现得像一组对,所以我期待2。
直观地说,它与C ++ std::map
行为不一致,insert
并不总是更改地图(而不是operator[]
)。
它背后有理由,还是随意的?
答案 0 :(得分:17)
Multimap只有一个谓词排序键。它没有方法来确定值是否相等。值“A”是值“a”的重复吗?没有值的第二个谓词,没有任何说明。因此,在多图中讨论重复值甚至没有意义。
如果您想要一个存储对的容器,并强制执行该对的两个部分的唯一性,请查看boost::multi_index_container
。它非常灵活,但结果却需要大量的参数。
答案 1 :(得分:11)
编辑:这个答案不再回答当前的问题了。我会保持原样,因为它已经投了很多,所以对某些人来说一定有用。
multimap
中的 multi 表示相同的键可以发生多次次。
标准对用作值的类型没有限制,因此不能假定operator==()
已定义。因为我们不希望代码的结果取决于是否定义了运算符==(),所以它永远不会被使用。
std::multimap
不是std::map
的替代品。正如您所注意到的,当多次插入相同的密钥时,它的行为会有所不同。如果您想要std::map
的行为,请使用std::map
。
还有std::multiset
。
理性:有时人们希望保留所有旧条目以获得相同的密钥。 [待定:在此处插入一些示例]
就个人而言,我几乎没有使用std::multimap
。如果我想要同一个密钥的多个条目,我通常依赖std::map<std::vector<T> >
。
答案 2 :(得分:2)
允许值重复,因为它们不需要相互比较。除了复制它们之外,容器不能对值执行任何操作。这样可以启用multimap< int, my_class >
等类型。
如果不希望使用重复的键值对,请使用set< pair< T, U > >
并使用lower_bound
查找给定键的第一个匹配项。
答案 3 :(得分:1)
如您所知,multimap
允许拥有多个密钥。由于它没有对价值可比性施加任何限制,因此无法检查价值是否未加倍。
如果您想要一些字典数据结构允许重复键,而不是键值对,则必须确保值具有可比性。
假设我们有一种类型的游戏,其中有二维世界的sqaure字段,你可以把项目放在字段上。您可以拥有multimap<Field, Item>
,这样您就可以在该字段上保留两个相同的项目。物品不一定要在这里比较。
答案 4 :(得分:1)
我的推理是multimap是基于Key查找/插入而不是值。因此,当插入元素时,重复键上的值是否相同不起作用。
23.3.2 类模板多图
1多图是一种关联 支持等效的容器 键(可能包含多个键) 相同键值的副本)和 提供快速检索值 基于键的另一种类型T。
答案 5 :(得分:0)
"multimap"旨在支持“多个”键,而不像简单的"map"。由于它允许多个键,因此不会为其值而烦恼,因此它在您的示例中显示了3个元素。另一个区别是,operator []
不能multimap
。
答案 6 :(得分:0)
使用重复的[map,value]对是为了计算一个单词在一个书页上出现的次数,无论是没有次数,因此在该单词的多重映射中都没有输入,只要用一个条目,或多个条目与make_pair(word,page_number)在multimap中的出现次数有关。设计是我偶然发现这种用法的。