2

C++ standard for "26.4.5.1 Class template multimap overview" p1 says:

A multimap is an 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.

emphasis is mine. So does it mean that std::multimap may not keep a copy of original key object when inserted into equal range and replace it with equal one?

PS To make clear this question is inspired by this Does Each Element of a multimap Contain Both the Key and Value? and I want to know if multimap allowed to do that ie can I rely on its ability to maintain my key (which could be equal but not the same).

R Sahu
  • 204,454
  • 14
  • 159
  • 270
Slava
  • 43,454
  • 1
  • 47
  • 90
  • Note that this is descriptive text, not a requirement. There's a lot of motivational text in the standard, especially in the parts that came more or less full-blown from the outside, such as the STL and much of the Boost stuff. Don't take it too seriously. – Pete Becker Apr 06 '18 at 15:51
  • It does not have to, an implementation __may__ keep all the values with the same key together just retaining one copy of the key. – Richard Critten Apr 06 '18 at 15:52
  • @RichardCritten this question is inspired by this one https://stackoverflow.com/questions/49695508/does-each-element-of-a-multimap-contain-both-the-key-and-value/49695590?noredirect=1#comment86405335_49695590 so I am not asking if it has to, but if it is allowed to do it. – Slava Apr 06 '18 at 15:53
  • 1
    Equivalent does not mean equal. So unless it is going to go to the effort of checking if two keys are equal (something that it may not be possible to do), it has to keep copies of all the keys. – 1201ProgramAlarm Apr 06 '18 at 15:54
  • @1201ProgramAlarm by equal I mean from multimap comparator point of view. – Slava Apr 06 '18 at 16:05
  • related https://stackoverflow.com/q/49695508/4117728 – 463035818_is_not_an_ai Apr 06 '18 at 16:16

2 Answers2

4

No. The standard describes how an element is inserted in this table. For example, the effect of a_­eq.​emplace(​args) is described as follows (emphasis mine).

Effects: Inserts a value_­type object t constructed with std​::​forward<​Args​>(​args)... and returns the iterator pointing to the newly inserted element. If a range containing elements equivalent to t exists in a_­eq, t is inserted at the end of that range.

Note the value_­type of std::multimap<Key, T> is std::pair<const Key, T>, so a same (not only equivalent) key must be constructed.

xskxzr
  • 12,442
  • 12
  • 37
  • 77
3

No, it doesn't mean that. multimap has to have a key associated with the object for every element. Here is normative wording:

26.4.5.1: A multimap is an associative container that supports equivalent keys (possibly containing multiple copies of the same key value)...

26.2.6: The phrase “equivalence of keys” means the equivalence relation imposed by the comparison object. That is, two keys k1 and k2 are considered to be equivalent if for the comparison object comp, comp(k1, k2) == false && comp(k2, k1) == false. [ Note: This is not necessarily the same as the result of k1 == k2. — end note ] For any two keys k1 and k2 in the same container, calling comp(k1, k2) shall always return the same value.

Since find and friends are required to return elements with their respective keys (also preserving relative ordering of equivalent elements!), there is no way conformant multimap can store a single key.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • 1
    Unfortunately your citation does not prove or disprove my concern. – Slava Apr 06 '18 at 15:56
  • @Slava You would need to inspect the implementation of standard library you are using. The phrasing of _"May"_ leaves it a (quality) of implementation detail. – Richard Critten Apr 06 '18 at 15:58
  • @RichardCritten the problem is inducing requirements from implementation is pretty bad thing to do, hence my question. – Slava Apr 06 '18 at 16:02
  • "here is no way conformant multimap can store a single key." it can store copy of the first key (not inserted one), this does not change anything, I am afraid. – Slava Apr 06 '18 at 16:03
  • @Slava The map must be able to return the key an entry was inserted with, which could be unequal to all the other equivalent keys. Equivalence is a weaker condition than equality. – molbdnilo Apr 06 '18 at 16:15
  • not sure but your answer seems to contradict this one https://stackoverflow.com/a/49695590/4117728 – 463035818_is_not_an_ai Apr 06 '18 at 16:15
  • @user463035818 Not that I can tell – Yakk - Adam Nevraumont Apr 06 '18 at 17:11
  • A multimap may contain multiples of the same key. That does not mean that the container may change your keys, it simply is an observation that `map[key0] = value1; map[key0] = value2;` results in the map containing two copies of `key0`, the same key value. – Yakk - Adam Nevraumont Apr 06 '18 at 17:12
  • @Yakk `map[key0]` does not apply to multimap – Slava Apr 06 '18 at 17:41
  • @Slava `map.insert({key0, value1}); map.insert({key0, value2});` Two copies of a key (which is equivalent to itself) in the multimap. In a map, something different happens. – Yakk - Adam Nevraumont Apr 06 '18 at 17:48