c++11 operator[] 是否等同于 emplace on map insertion?

Is c++11 operator[] equivalent to emplace on map insertion?

对于C++11,下面还有性能差异吗?

(以std::map<Foo, std::vector<Bar> >为例)

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

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

  1. 在映射中的适当位置创建一个新键和关联的空默认向量
  2. Return关联空向量的引用
  3. 将 myVector 分配给引用???

第3点是我没看懂的部分,你怎么能一开始就给一个引用赋新值?

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

两者之间存在很多的差异。

如果你使用operator[],那么map默认构造值。来自 operator[] 的 return 值将是这个默认构造的对象,然后将使用 operator= 分配给它。

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

因此operator[]方法将始终使用两阶段构造。如果默认构造函数很慢,或者如果 copy/move 构造比 copy/move 赋值快,那么它可能会有问题。

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

还有其他差异。如果 copying/moving 抛出,emplace 保证 map 不会被改变 。相比之下,operator[] 将始终插入默认构造的元素。所以如果后面的 copy/move 赋值失败,那么 map 已经被改变了。该密钥将以默认构造 value_type.

存在

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

C++17 将 provide insert_or_assign,具有 map[] = v; 的效果,但 insert/emplace.

的安全性除外

how can you assign a new value to a reference in the first place?

这与分配给 any non-const reference:

根本没有区别
int i = 5;
int &j = i;
j = 30;
i == 30; //This is true.