为什么multimap允许重复的键值对?

时间:2023-01-06 19:16:27

EDIT: Please note, I'm NOT asking why multimap can't contain duplicate keys.

编辑:请注意,我不是在问为什么multimap不能包含重复键。

What's the rationale behind multimap allowing duplicate key-value pairs? (not keys)

允许重复键值对的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;
}

This printed 3, which somewhat surprised me, I expected multimap to behave like a set of pairs, so I was expecting 2.

这打印3,有点让我感到惊讶,我期望multimap表现得像一对对,所以我期待2。

Intuitively, it's not consistent with C++ std::map behaviour, where insert does not always change the map (as opposed to operator[]).

直观地说,它与C ++ std :: map行为不一致,其中insert并不总是改变映射(而不是operator [])。

Is there a rationale behind it, or it's just arbitrary?

它背后有理由,还是随意的?

6 个解决方案

#1


17  

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.

Multimap只有一个谓词排序键。它没有方法来确定值是否相等。值“A”是值“a”的重复吗?没有值的第二个谓词,没有任何说明。因此,在多图中讨论重复值甚至没有意义。

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.

如果您想要一个存储对的容器,并强制执行该对的两个部分的唯一性,请查看boost :: multi_index_container。它非常灵活,但结果却需要大量的参数。

#2


11  

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.

multi in multimap代表相同密钥可以多次出现的事实。

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.

标准对用作值的类型没有限制,因此不能假设定义了operator ==()。因为我们不希望代码的结果取决于是否定义了运算符==(),所以从不使用它。

std::multimap is not a replacement for std::map. As you noticed, it behaves differently when the same key is inserted multiple times. If you want std::map's behaviour, use std::map.

std :: multimap不是std :: map的替代品。正如您所注意到的,当多次插入相同的密钥时,它的行为会有所不同。如果你想要std :: map的行为,请使用std :: map。

There is also a std::multiset.

还有一个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 on std::map<std::vector<T> >.

就个人而言,我几乎没有使用过std :: multimap。如果我想要同一个键的多个条目,我通常依赖于std :: map >。

#3


2  

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 >.

允许这些值是重复的,因为它们不需要彼此相当。除了复制它们之外,容器不能对值执行任何操作。这样可以启用multimap 等类型。 ,my_class>

If duplicate key-value pairs are undesirable, then use set< pair< T, U > > and use lower_bound to find the first match to a given key.

如果不希望有重复的键值对,则使用set >>并使用lower_bound查找给定键的第一个匹配项。

#4


1  

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.

如您所知,multimap允许拥有多个键。由于它没有对价值可比性施加任何限制,因此如果价值没有加倍,则无法检查。

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.

假设我们有一种类型的游戏,其中有2D世界的sqaure字段,你可以把项目放在字段上。您可以使用multimap ,这将允许您在字段上保留两个相同的项目。物品不一定要在这里比较。 ,item>

#5


1  

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.

我的推理是multimap是基于Key查找/插入而不是值。因此,当插入元素时,重复键上的值是否相同不起作用。

23.3.2 Class template multimap

23.3.2类模板多图

1 A multimap is a kind of associative container that supports equivalent keys (possibly containing multiple copies of the same key value) and provides for fast retrieval of values of another type T based on the keys.

1 multimap是一种关联容器,它支持等效键(可能包含相同键值的多个副本),并提供基于键快速检索另一种类型T的值。

#6


0  

"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 [] for multimap.

“multimap”意味着支持“多个”键,而不像简单的“map”。由于它允许多个键,因此不会为其值而烦恼,因此它在您的示例中显示了3个元素。另一个区别是,一个人不能拥有multimap的operator []。

#1


17  

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.

Multimap只有一个谓词排序键。它没有方法来确定值是否相等。值“A”是值“a”的重复吗?没有值的第二个谓词,没有任何说明。因此,在多图中讨论重复值甚至没有意义。

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.

如果您想要一个存储对的容器,并强制执行该对的两个部分的唯一性,请查看boost :: multi_index_container。它非常灵活,但结果却需要大量的参数。

#2


11  

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.

multi in multimap代表相同密钥可以多次出现的事实。

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.

标准对用作值的类型没有限制,因此不能假设定义了operator ==()。因为我们不希望代码的结果取决于是否定义了运算符==(),所以从不使用它。

std::multimap is not a replacement for std::map. As you noticed, it behaves differently when the same key is inserted multiple times. If you want std::map's behaviour, use std::map.

std :: multimap不是std :: map的替代品。正如您所注意到的,当多次插入相同的密钥时,它的行为会有所不同。如果你想要std :: map的行为,请使用std :: map。

There is also a std::multiset.

还有一个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 on std::map<std::vector<T> >.

就个人而言,我几乎没有使用过std :: multimap。如果我想要同一个键的多个条目,我通常依赖于std :: map >。

#3


2  

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 >.

允许这些值是重复的,因为它们不需要彼此相当。除了复制它们之外,容器不能对值执行任何操作。这样可以启用multimap 等类型。 ,my_class>

If duplicate key-value pairs are undesirable, then use set< pair< T, U > > and use lower_bound to find the first match to a given key.

如果不希望有重复的键值对,则使用set >>并使用lower_bound查找给定键的第一个匹配项。

#4


1  

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.

如您所知,multimap允许拥有多个键。由于它没有对价值可比性施加任何限制,因此如果价值没有加倍,则无法检查。

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.

假设我们有一种类型的游戏,其中有2D世界的sqaure字段,你可以把项目放在字段上。您可以使用multimap ,这将允许您在字段上保留两个相同的项目。物品不一定要在这里比较。 ,item>

#5


1  

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.

我的推理是multimap是基于Key查找/插入而不是值。因此,当插入元素时,重复键上的值是否相同不起作用。

23.3.2 Class template multimap

23.3.2类模板多图

1 A multimap is a kind of associative container that supports equivalent keys (possibly containing multiple copies of the same key value) and provides for fast retrieval of values of another type T based on the keys.

1 multimap是一种关联容器,它支持等效键(可能包含相同键值的多个副本),并提供基于键快速检索另一种类型T的值。

#6


0  

"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 [] for multimap.

“multimap”意味着支持“多个”键,而不像简单的“map”。由于它允许多个键,因此不会为其值而烦恼,因此它在您的示例中显示了3个元素。另一个区别是,一个人不能拥有multimap的operator []。