Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do STL maps initialize primitive types on insert?

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.

like image 894
Calmarius Avatar asked Feb 03 '09 17:02

Calmarius


People also ask

Does insert overwrite map C++?

insert() doesn't overwrite.

Are maps initialized to 0?

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) .

What is an insert on a map?

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.


4 Answers

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.

like image 78
Todd Gamblin Avatar answered Oct 03 '22 07:10

Todd Gamblin


This will default-construct a new instance of value. For integers, the default construction is 0, so this works as intended.

like image 23
hazzen Avatar answered Oct 03 '22 05:10

hazzen


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.

like image 21
Michael Kristofik Avatar answered Oct 03 '22 05:10

Michael Kristofik


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.

like image 38
Ketan Avatar answered Oct 03 '22 07:10

Ketan