insert vs emplace vs operator[] in c++ map -


i'm using maps first time , realized there many ways insert element. can use emplace(), operator[] or insert(), plus variants using value_type or make_pair. while there lot of information of them , questions particular cases, still can't understand big picture. so, 2 questions are:

  1. what advantage of each 1 of them on others?

  2. was there need adding emplace standard? there wasn't possible before without it?

in particular case of map old options two: operator[] , insert (different flavors of insert). start explaining those.

the operator[] find-or-add operator. try find element given key inside map, , if exists return reference stored value. if not, create new element inserted in place default initialization , return reference it.

the insert function (in single element flavor) takes value_type (std::pair<const key,value>), uses key (first member) , tries insert it. because std::map not allow duplicates if there existing element not insert anything.

the first difference between 2 operator[] needs able construct default initialized value, , unusable value types cannot default initialized. second difference between 2 happens when there element given key. insert function not modify state of map, instead return iterator element (and false indicating not inserted).

// assume m std::map<int,int> has element key 5 , value 0 m[5] = 10;                      // postcondition: m[5] == 10 m.insert(std::make_pair(5,15)); // m[5] still 10 

in case of insert argument object of value_type, can created in different ways. can directly construct appropriate type or pass object value_type can constructed, std::make_pair comes play, allows simple creation of std::pair objects, although not want...

the net effect of following calls similar:

k t; v u; std::map<k,v> m;           // std::map<k,v>::value_type std::pair<const k,v>  m.insert( std::pair<const k,v>(t,u) );      // 1 m.insert( std::map<k,v>::value_type(t,u) ); // 2 m.insert( std::make_pair(t,u) );            // 3 

but not same... [1] , [2] equivalent. in both cases code creates temporary object of same type (std::pair<const k,v>) , passes insert function. insert function create appropriate node in binary search tree , copy value_type part argument node. advantage of using value_type that, well, value_type matches value_type, cannot mistype type of std::pair arguments!

the difference in [3]. function std::make_pair template function create std::pair. signature is:

template <typename t, typename u> std::pair<t,u> make_pair(t const & t, u const & u ); 

i have intentionally not provided template arguments std::make_pair, common usage. , implication template arguments deduced call, in case t==k,u==v, call std::make_pair return std::pair<k,v> (note missing const). signature requires value_type close not same returned value call std::make_pair. because close enough create temporary of correct type , copy initialize it. in turn copied node, creating total of 2 copies.

this can fixed providing template arguments:

m.insert( std::make_pair<const k,v>(t,u) );  // 4 

but still error prone in same way explicitly typing type in case [1].

up point, have different ways of calling insert require creation of value_type externally , copy of object container. alternatively can use operator[] if type default constructible , assignable (intentionally focusing in m[k]=v), , requires default initialization of 1 object , copy of value object.

in c++11, variadic templates , perfect forwarding there new way of adding elements container means of emplacing (creating in place). emplace functions in different containers same thing: instead of getting source copy container, function takes parameters forwarded constructor of object stored in container.

m.emplace(t,u);               // 5 

in [5], std::pair<const k, v> not created , passed emplace, rather references t , u object passed emplace forwards them constructor of value_type subobject inside data structure. in case no copies of std::pair<const k,v> done @ all, advantage of emplace on c++03 alternatives. in case of insert not override value in map.


an interesting question had not thought how emplace can implemented map, , not simple problem in general case.


Comments

Popular posts from this blog

php - Vagrant up error - Uncaught Reflection Exception: Class DOMDocument does not exist -

vue.js - Create hooks for automated testing -

Add new key value to json node in java -