我第一次使用地图,我意识到有很多方法可以插入元素。 You can use emplace()
, operator[]
or insert()
, plus variants like using value_type
or make_pair
.虽然有很多关于所有这些的信息和关于特定案例的问题,但我仍然无法理解大局。所以,我的两个问题是:
他们每个人比其他人有什么优势?
是否需要在标准中添加 emplace?没有它,有什么是不可能的吗?
原文由 German Capuano 发布,翻译遵循 CC BY-SA 4.0 许可协议
在地图的特定情况下,旧选项只有两个:
operator[]
和insert
(不同风格的insert
)。所以我将开始解释这些。operator[]
是一个 查找或添加 运算符。它将尝试在地图中查找具有给定键的元素,如果存在,它将返回对存储值的引用。如果没有,它将使用默认初始化创建一个插入到位的新元素并返回对它的引用。The
insert
function (in the single element flavor) takes avalue_type
(std::pair<const Key,Value>
), it uses the key (first
member) and试图插入它。因为std::map
如果存在现有元素则不允许重复,因此不会插入任何内容。两者的第一个区别是
operator[]
需要能够构造一个默认的初始化 _值_,因此不能用于不能默认初始化的值类型。两者之间的第二个区别是当已经存在具有给定键的元素时会发生什么。insert
函数不会修改映射的状态,而是返回一个迭代器到元素(和一个false
表明它没有被插入)。在
insert
value_type
对象,可以通过不同的方式创建。您可以使用适当的类型直接构造它,或传递可以构造value_type
的任何对象,这就是std::make_pair
发挥作用的地方,因为它允许简单地创建std::pair
对象,虽然它可能不是你想要的……以下调用的净效果是 相似 的:
但实际上并不相同…… [1] 和 [2] 实际上是等价的。在这两种情况下,代码都会创建一个相同类型的临时对象(
std::pair<const K,V>
)并将其传递给insert
函数。insert
函数将在二叉搜索树中创建适当的节点,然后将value_type
部分从参数复制到节点。 The advantage of usingvalue_type
is that, well,value_type
always matchesvalue_type
, you cannot mistype the type of thestd::pair
arguments!区别在[3]。函数
std::make_pair
是一个模板函数,它将创建一个std::pair
。签名是:我故意不向
std::make_pair
提供模板参数,因为这是常用的用法。这意味着模板参数是从调用中推导出来的,在本例中为T==K,U==V
,因此对std::make_pair
的调用将返回一个std::pair<K,V>
缺失的const
)。签名需要value_type
接近 但与调用std::make_pair
的返回值不同。因为它足够接近,它将创建一个正确类型的临时文件并复制初始化它。这将依次复制到节点,总共创建两个副本。这可以通过提供模板参数来解决:
但这仍然容易出错,就像在 case [1] 中显式键入类型一样。
到目前为止,我们有不同的调用方式
insert
需要在外部创建value_type
并将该对象的副本复制到容器中。或者,您可以使用operator[]
如果类型是 默认可构造 和 可分配 的(故意只关注m[k]=v
),它需要一个对象的默认初始化并将值 复制 到该对象中目的。在 C++11 中,通过可变参数模板和完美转发,有一种新方法可以通过 _放置_(就地创建)将元素添加到容器中。不同容器中的
emplace
函数基本上做同样的事情:该函数不是获取 复制 到容器的 _源_,而是获取将转发给存储在容器。In [5], the
std::pair<const K, V>
is not created and passed toemplace
, but rather references to thet
andu
object are passed到emplace
将它们转发到数据结构内的value_type
子对象的构造函数。在这种情况下, 根本不会 复制std::pair<const K,V>
,这是emplace
优于 C++03 替代方案的优势。就像insert
它不会覆盖地图中的值。一个我没有想到的有趣问题是
emplace
可以如何实际用于地图,这在一般情况下不是一个简单的问题。