I have some (C++14) code that looks like this:
map> junk;
for (int id : GenerateIds()) {
try {
set stuff =
You're misunderstanding how operator[]
works on std::map
.
It returns a reference to the mapped item. Therefore, your code is first inserting a default item in that position and then invoking operator=
to set a new value.
To make this work the way you expect, you'll need to use std::map::insert
(*):
junk.insert(std::make_pair(id, GetStuff()));
Caveat: insert
will only add the value if id
is not already mapped.
Before C++17 there was no sequencing between the left- and right-hand side of assignment operators.
It's first in C++17 that explicit sequencing was introduced (right-hand side is evaluated first).
That means the evaluation order is unspecified, which means it's up to the implementation to perform the evaluation in the order in which it wants, and in this case it evaluates the left-hand side first.
See this evaluation order reference for more details (especially point 20).
std::map::operator[]
Returns a reference to the value that is mapped to a key equivalent to key, performing an insertion if such key does not already exist.
junk[id]
causes the above mentioned insertion and after that has already happened GetStuff()
throws. Note that in C++14 the order in which these things happen is implementation defined so with a different compiler your junk[id] = GetStuff();
may not do the insertion if GetStuff()
throws.