This is LWG 334:
C++03 标准要求以下效果:operator[]
([lib.map.access]p1):
Returns: (*((insert(make_pair(x, T()))).first)).second
.
libstdc++ 实现了使用的插入operator[]
(在key还不存在的情况下)在C++03模式下如下:
__i = insert(__i, value_type(__k, mapped_type()));
__i
是插入点,计算公式为
iterator __i = lower_bound(__k);
__k
是参数operator[]
.
临时的创建value_type(__k, mapped_type())
导致第一个副本(来自mapped_type()
进入value_type
一对)。第二个副本的结果是insert
,它复制了value_type
配对成实际节点。
1997 年的原始版本是:
return (*((insert(value_type(k, T()))).first)).second;
这几乎符合标准的字面意思(当时甚至不存在!)。上次对其进行重大更改是在 1998 年。在此之前,它使用:
__i = insert(__i, value_type(__k, _Tp()));
提交消息说这是为了
更新至 SGI STL 3.11。
SGI STL 的早期版本 (1995)确实指定了map::operator[]
与 C++03 标准相同:
对于地图m
和钥匙k
, m[k]
在语义上等价于(*((m.insert(make_pair(k, T()))).first)).second
.
SGI STL v2.03 (1997) 已经改用value_type
代替make_pair
。正如 gcc 的提交日志所表明的那样,SGI STL 的实现在 v3.0(也是 1997 年)和 v3.11(1998 年)之间再次发生了变化insert(value_type(..
使用 libstdc++ 中仍然存在的形式lower_bound
并且仅在密钥尚不存在时才创建该对。
所以可以说 libstdc++ 实现了 LWG 334 的第一个提议的决议(value_type
代替make_pair
)。然而,纵观其历史,事实并非如此。它只是以下SGI STL。 libc++ 在这方面并不严格符合 C++03。
libstdc++ 的 C++11 版本的同一运算符使用自定义定位函数。 C++11 标准的规范map::operator[]
遵循 LWG 334 的拟议决议:
Effects:如果没有相当于的键x
在地图中,插入value_type(x, T())
进入地图。
(where x
是参数operator[]
)