Consider this code:
#include
#include
#include This is LWG 334:
The C++03 Standard mandates the following effects for operator[] ([lib.map.access]p1):
Returns:
(*((insert(make_pair(x, T()))).first)).second.
libstdc++ implements the insertion used by operator[] (in the case where the key doesn't exist yet) as follows in C++03 mode:
__i = insert(__i, value_type(__k, mapped_type()));
__i is the insertion point, it is computed as
iterator __i = lower_bound(__k);
__k is the parameter of operator[].
The creation of the temporary value_type(__k, mapped_type()) causes the first copy (from mapped_type() into the value_type pair). The second copy is the result of insert, which copies the value_type pair into an actual node.
The original version from 1997 is:
return (*((insert(value_type(k, T()))).first)).second;
which is almost to the letter of the Standard (which didn't even exist back then!). The last time it was changed significantly was in 1998. Prior to that, it used:
__i = insert(__i, value_type(__k, _Tp()));
The commit message says this was to
Update to SGI STL 3.11.
Earlier versions of the SGI STL (1995) did indeed specify map::operator[] in the same way as the C++03 Standard:
For a map
mand keyk,m[k]is semantically equivalent to(*((m.insert(make_pair(k, T()))).first)).second.
SGI STL v2.03 (1997) had already switched to using value_type instead of make_pair. And as gcc's commit log suggests, SGI STL's implementation changed again between v3.0 (also 1997) and v3.11 (1998) from insert(value_type(.. to the form still present in libstdc++ using lower_bound and only creating the pair if the key doesn't exist yet.
So one could say that libstdc++ implements the first proposed resolution of LWG 334 (value_type instead of make_pair). This isn't exactly what happened, though, looking at its history. It's simply following SGI STL. libc++ doesn't strictly conform to C++03 in this respect.
libstdc++'s C++11 version of the same operator uses a custom emplacement function. The C++11 Standard's specification of map::operator[] follows the proposed resolution of LWG 334:
Effects: If there is no key equivalent to
xin the map, insertsvalue_type(x, T())into the map.
(where x is the parameter of operator[])