Reputation: 39119
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.
Upvotes: 3
Views: 1752
Reputation:
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<...> >
Upvotes: 2
Reputation: 7647
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.
Upvotes: 2