Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid unnecessary constructor calls while inserting element to std::unordered_map?

Tags:

c++

c++11

stl

Say I have std::unordered_map < int, std::vector< int > > my_hashtable and I insert a new entry:

my_hashtable.insert(make_pair(a_key, std::vector()));

This works but it invokes constructors and assignment ops multiple times. (1) std::vector(), (2) make_pair arguments are pass by value, copy (3) make_pair return type by value, copy again (4) function insert will make copy again.

Please correct me if I count it incorrectly.

Hence, we are making too many copies, we really only should call constructor once, how can we achieve that (under C++11)?

I noticed that std::unordered_map::insert has a version working with move constructor, but not sure how to use that.

like image 369
szli Avatar asked Jul 01 '26 15:07

szli


2 Answers

You can check the examples of std::unordered_map::emplace():

my_hashtable.emplace(
   std::piecewise_construct,
   std::forward_as_tuple(a_key),
   std::forward_as_tuple()
);

Here, there is no unnecessary constructor call.

like image 111
iavr Avatar answered Jul 04 '26 04:07

iavr


The problem is the signature of the value_type of the map: It is std::pair<map::key_type, map::mapped_type> where the key type is const qualified.

This will eliminate a copy/move:

typedef std::unordered_map < int, std::vector< int > > hash_table:
my_hashtable.insert(hash_table::value_type(a_key, std::vector()));

The signature of the result of make_pair in your example is likely std::pair<int, vector<...> > and not std::pair<const int, vector<...> >