A while ago, I had a discussion with a colleague about how to insert values in STL maps. I preferred
map[key] = value;
because it feels natural and is clear to read whereas he preferred
map.insert(std::make_pair(key, value))
I just asked him and neither of us can remember the reason why insert is better, but I am sure it was not just a style preference rather there was a technical reason such as efficiency. The SGI STL reference simply says "Strictly speaking, this member function is unnecessary: it exists only for convenience."
Can anybody tell me that reason, or am I just dreaming that there is one?
When you write
there's no way to tell if you replaced the
value
forkey
, or if you created a newkey
withvalue
.map::insert()
will only create:For most of my apps, I usually don't care if I'm creating or replacing, so I use the easier to read
map[key] = value
.The two have different semantics when it comes to the key already existing in the map. So they aren't really directly comparable.
But the operator[] version requires default constructing the value, and then assigning, so if this is more expensive then copy construction, then it will be more expensive. Sometimes default construction doesn't make sense, and then it would be impossible to use the operator[] version.
The fact that std::map
insert()
function doesn't overwrite value associated with the key allows us to write object enumeration code like this:It's a pretty common problem when we need to map different non-unique objects to some id's in range 0..N. Those id's can be later used, for example, in graph algorithms. Alternative with
operator[]
would look less readable in my opinion:One note is that you can also use Boost.Assign:
If your application is speed critical i will advice using [] operator because it creates total 3 copies of the original object out of which 2 are temporary objects and sooner or later destroyed as.
But in insert(), 4 copies of the original object are created out of which 3 are temporary objects( not necessarily "temporaries") and are destroyed.
Which means extra time for: 1. One objects memory allocation 2. One extra constructor call 3. One extra destructor call 4. One objects memory deallocation
If your objects are large, constructors are typical, destructors do a lot of resource freeing, above points count even more. Regarding readability, i think both are fair enough.
The same question came into my mind but not over readability but speed. Here is a sample code through which I came to know about the point i mentioned.
If the performance hit of the default constructor isn't an issue, the please, for the love of god, go with the more readable version.
:)