1

对于 C++11,以下之间是否还有性能差异?

std::map<Foo, std::vector<Bar> >例如)

map[key] = myVector and map.emplace(key, myVector)

我没有弄清楚的部分是 operator[] 的确切内部。到目前为止,我的理解是(当密钥不存在时):

  1. 在地图内的适当位置创建一个新键和关联的空默认向量
  2. 返回关联空向量的引用
  3. 将 myVector 分配给参考???

第 3 点是我无法理解的部分,首先如何为引用分配新值?

尽管我无法对第 3 点进行排序,但我认为不知何故只需要复制/移动。假设 C++11 足够聪明,知道这将是一个移动操作,那么整个“[]”赋值是否已经比 insert() 便宜?它几乎等同于 emplace() 吗?---- 默认构造和移动内容,与直接在适当位置构造内容的向量?

4

1 回答 1

3

两者之间有很多不同之处。

如果使用operator[]map则将默认构造该值。from 的返回值operator[]将是这个默认构造的对象,然后将operator=用于分配给它。

如果使用emplacemap将直接使用您提供的参数构造值。

因此该operator[]方法将始终使用两阶段构建。如果默认构造函数很慢,或者如果复制/移动构造比复制/移动分配快,那么它可能会出现问题。

但是,如果提供的键已经存在,emplace则不会替换该值。operator[]随后operator=将始终替换该值,无论那里是否存在。

还有其他差异。如果复制/移动抛出,emplace保证map 不会改变。相比之下,operator[]总是会插入一个默认的构造元素。因此,如果以后的复制/移动分配失败,则map已经更改。该键将与默认构造一起存在value_type

确实,在决定使用哪一个时,性能并不是您应该考虑的第一件事。您需要首先关注它是否具有所需的行为。

C++17 将提供insert_or_assign,其效果为map[] = v;,但安全性为insert/emplace.

如何首先为引用分配新值?

这与分配给任何const引用基本上没有什么不同:

int i = 5;
int &j = i;
j = 30;
i == 30; //This is true.
于 2016-08-27T02:29:12.073 回答