I have a std::map
like this:
map<wstring,int> Scores;
It stores names of players and scores. When someone gets a score I would simply do:
Scores[wstrPlayerName]++;
When there is no element in the map with the key wstrPlayerName
it will create one, but does it initialize to zero or null before the increment or is it left undefined?
Should I test if the element exists every time before increment?
I just wondered because I thought primitive-type things are always undefined when created.
If I write something like:
int i;
i++;
The compiler warns me that i is undefined and when I run the program it is usually not zero.
insert() doesn't overwrite.
When this map is accessed with the [ ] (e.g map<int,int> mpp; mpp[1]; ) if the key is not present in the map , it gets added and its value is by default set to 0 (i.e value initialization gets invoked for the int) .
An inset map is a smaller map featured on the same page as the main map. Traditionally, inset maps are shown at a larger scale (smaller area) than the main map. Often, an inset map is used as a locator map that shows the area of the main map in a broader, more familiar geographical frame of reference.
operator[] looks like this:
Value& map<Key, Value>::operator[](const Key& key);
If you call it with a key that's not yet in the map, it will default-construct a new instance of Value, put it in the map under key you passed in, and return a reference to it. In this case, you've got:
map<wstring,int> Scores;
Scores[wstrPlayerName]++;
Value here is int, and ints are default-constructed as 0, as if you initialized them with int(). Other primitive types are initialized similarly (e.g., double(), long(), bool(), etc.).
In the end, your code puts a new pair (wstrPlayerName, 0) in the map, then returns a reference to the int, which you then increment. So, there's no need to test if the element exists yet if you want things to start from 0.
This will default-construct a new instance of value
. For integers, the default construction is 0, so this works as intended.
You should not test if the item exists before incrementing it. The [] operator does exactly what you need it to do, as others have said.
But what if the default-constructed value wouldn't work for you? In your case the best way to find if the element already exists is to try to insert it. The insert
member function for std::map
returns a std::pair<iterator, bool>
. Whether the insert succeeds or fails, the first element of the pair will point to the desired object (either your new one, or the one that was already present). You can then alter its value as you see fit.
Check rules for initialization.
See section 4.9.5 Initialization of C++ Prog Lang or C++ std book. Depending on whether your variable is local, static, user-defined or const default initialization can happen.
In you case, int is called POD (Plain old Datatype). Any auto (created on heap / local variable) POD variable is not default initialized. Hence for you "i" above will not have value zero.
Always make an habit of initializing POD when defined in heap. You can even use int() to initialize value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With