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

六月ゝ 毕业季﹏ 提交于 2020-01-05 04:14:08

问题


For C++11, is there still a performance difference between the following?

(for std::map<Foo, std::vector<Bar> > as an example)

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

The part I'm not figuring out is the exact internal of operator[]. My understanding so far has been (when key doesn't exist):

  1. Create a new key and the associated empty default vector in place inside the map
  2. Return the reference of the associated empty vector
  3. Assign myVector to the reference???

The point 3 is the part I couldn't understand, how can you assign a new value to a reference in the first place?

Though I cannot sort through point 3 I think somehow there's just a copy/move required. Assuming C++11 will be smart enough to know it's gonna be a move operation, is this whole "[]" assignment then already cheaper than insert()? Is it almost equivalent to emplace()? ---- default construction and move content over, versus construct vector with content directly in place?


回答1:


There are a lot of differences between the two.

If you use operator[], then the map will default construct the value. The return value from operator[] will be this default constructed object, which will then use operator= to assign to it.

If you use emplace, the map will directly construct the value with the parameters you provide.

So the operator[] method will always use two-stage construction. If the default constructor is slow, or if copy/move construction is faster than copy/move assignment, then it could be problematic.

However, emplace will not replace the value if the provided key already exists. Whereas operator[] followed by operator= will always replace the value, whether there was one there or not.

There are other differences too. If copying/moving throws, emplace guarantees that the map will not be changed. By contrast, operator[] will always insert a default constructed element. So if the later copy/move assignment fails, then the map has already been changed. That key will exist with a default constructed value_type.

Really, performance is not the first thing you should be thinking about when deciding which one to use. You need to focus first on whether it has the desired behavior.

C++17 will provide insert_or_assign, which has the effect of map[] = v;, but with the exception safety of insert/emplace.

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

It's fundamentally no different from assigning to any non-const reference:

int i = 5;
int &j = i;
j = 30;
i == 30; //This is true.


来源:https://stackoverflow.com/questions/39176770/is-c11-operator-equivalent-to-emplace-on-map-insertion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!