Consider the following code:
std::map<int, int> m;
int &ref = m[0];
int *ptr = &m[0];
m.insert({1,2});
std::cout << ref; // #1
std::cout << *ptr; // #2
For an associative container like std::map
, the standard says:
The insert and emplace members shall not affect the validity of iterators and references to the container, ...
Which means #1
is definitely ok. However, I'm not so sure about #2
.
This question has been asked and answer over a decade ago.
The accepted answer says #2
is technically not allowed but will work in practice.
The consensus answer (with more than twice the number of up-votes than the accepted answer) says #2
is ok, by simply saying that the above standard quote implies pointers are not invalidated as well.
There are also at least half a dozen relatively more recent duplicates of this question, most of them with answers, and all of them say #2
is ok, usually by quoting the same standard text above.
I don't think this is correct. To my understanding, references are not pointers, and one can't be substituted for the other, whether they are implemented in terms of each other or not. As a comparison, here's what the standard says about the validity of referents to elements in unordered associative containers, upon rehashing:
Rehashing invalidates iterators, ..., but does not invalidate pointers or references to elements.
This explicitly guarantees pointers' validity, suggesting that the validity of references does not automatically imply it.
So does the language say #2
is ok? And is it implied by the validity of #1
?