Officially, either side of the assignment could be evaluated first. It's up to the implementation to decide which. If word_count
does not contain an "a"
, one is inserted, and an lvalue reference to it returned. If word_count
does contain one, only the latter part happens. Despite the uncertainty of which side is evaluated first, you can follow possible executions:
Left Side First
No Element Exists:
operator[]
inserts the element since it isn't already there. count()
finds it and returns 1, so you end up with it being assigned a value of 2.
Element Exists:
operator[]
returns the existing element and count()
finds it and returns 1, so you end up with it being assigned a value of 2.
Right Side First
No Element Exists:
count()
returns 0, so you get 1 from the right side. Then, "a"
is inserted into the map and assigned a value of 1.
Element Exists:
count()
returns 1, so you get 2 from the right side. Then, word_count["a"]
is accessed and has 2 assigned to it.
Conclusion
In short, you can't rely on this to do what you want, so it's better to use something that you can rely on. mrfontanini made a good suggestion, so I'll edit it a bit:
word_count["a"]++;
word_count["a"] = std::min(word_count["a"], 2);
The first line ensures it is inserted and has a value of at least 1. The second limits that value to a maximum 2, in the case that you do this operation repeatedly.
Notes
I base this answer off of two things:
When a side is picked to be evaluated, the whole side has to be evaluated before the other side can start.
Constructs such as word_count["a"] = 1
exhibit well-defined behaviour, even in the case that an element is inserted and then assigned to.
There is some debate and discussion below about whether these are true or not. I've made it a bit more official now.
word_count["a"]++
shorter/easier? – Salzburgmin()
if used repeatedly to limit it to 2. – Scalpel