3

According to http://www.cplusplus.com/reference/map/multimap/emplace_hint/

The relative ordering of equivalent elements is preserved, and newly inserted elements follow their equivalents already in the container.

The value in position is used as a hint on the insertion point. The element will nevertheless be inserted at its corresponding position following the order described by its internal comparison object, but this hint is used by the function to begin its search for the insertion point, speeding up the process considerably when the actual insertion point is either position or close to it.

As I understand, the hint is just a hint and should not affect the ordering at all. But it seems that it is not the case for both clang++(11) and g++(10), no matter the options or c++ the standard specified.

 int main()
{
    std::multimap<int, string> mymap;
    // emplace
    mymap.emplace(0, "First");
    mymap.emplace(0, "Second");

    // emplace_hint
    mymap.emplace_hint(mymap.end(), 1, "First");
    // Insert with the previously inserted element as hint
    mymap.emplace_hint(--mymap.end(), 1, "Second");

    for (auto it = mymap.begin(); it != mymap.end(); ++it) {
        std::cout << it->first << " " << it->second << std::endl;
    }
    return 0;
}

Outputs

0 First
0 Second
1 Second
1 First

Is this the expected behavior?

1 Answers1

1

That cite, from cplusplus.com, appears to be in error. From the C++ standard:

22.2.6 Associative containers [associative.reqmts]

...

An associative container supports unique keys if it may contain at most one element for each key. Otherwise, it supports equivalent keys. The set and map classes support unique keys; the multiset and multimap classes support equivalent keys. For multiset and multimap, insert, emplace, and erase preserve the relative ordering of equivalent elements.

Note that only emplace is listed, but not emplace_hint.

The same identical wording appears in the C++11 standard, as well as the current standard, so this wording has not been changed any time recently.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • I guess there is no way to specify a hint when we want to insert right after an iterator which has the same key. Maybe `mymap.emplace_hint(next(it), key, val)`. But if the next element has the same key, I am not sure it will work. – Sébastien Faucheux Dec 25 '20 at 04:49