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[] 的确切内部。到目前为止,我的理解是(当密钥不存在时):
- 在映射中的适当位置创建一个新键和关联的空默认向量
- Return关联空向量的引用
- 将 myVector 分配给引用???
第3点是我没看懂的部分,你怎么能一开始就给一个引用赋新值?
虽然我无法对第 3 点进行排序,但我认为不知何故只需要 copy/move。假设 C++11 足够聪明,知道它是一个移动操作,那么整个“[]”赋值是否已经比 insert() 更便宜了?它几乎等同于 emplace() 吗? ---- 默认构造并移动内容,与直接在适当位置构造带有内容的向量?
两者之间存在很多的差异。
如果你使用operator[]
,那么map
将默认构造值。来自 operator[]
的 return 值将是这个默认构造的对象,然后将使用 operator=
分配给它。
如果你使用emplace
,map
会直接用你提供的参数构造值。
因此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.
对于C++11,下面还有性能差异吗?
(以std::map<Foo, std::vector<Bar> >
为例)
map[key] = myVector and map.emplace(key, myVector)
我没有搞清楚的部分是 operator[] 的确切内部。到目前为止,我的理解是(当密钥不存在时):
- 在映射中的适当位置创建一个新键和关联的空默认向量
- Return关联空向量的引用
- 将 myVector 分配给引用???
第3点是我没看懂的部分,你怎么能一开始就给一个引用赋新值?
虽然我无法对第 3 点进行排序,但我认为不知何故只需要 copy/move。假设 C++11 足够聪明,知道它是一个移动操作,那么整个“[]”赋值是否已经比 insert() 更便宜了?它几乎等同于 emplace() 吗? ---- 默认构造并移动内容,与直接在适当位置构造带有内容的向量?
两者之间存在很多的差异。
如果你使用operator[]
,那么map
将默认构造值。来自 operator[]
的 return 值将是这个默认构造的对象,然后将使用 operator=
分配给它。
如果你使用emplace
,map
会直接用你提供的参数构造值。
因此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.