The problem with this is that the huge objects will be copied into the maps
Huge huge1(some,args);
Huge huge2(some,args);
std::map<int,Huge> map1;
std::map<Huge,int> map2;
map1.insert({0,huge1});
map2.insert({huge2,0});
how can I guarantee a move? Will this work or is there more to it?
map1.insert({0,std::move(huge1)});
map2.insert({std::move(huge2),0});
std::map::insert
has an overload for R-values:
std::pair<iterator,bool> insert(value_type&&);
Any expression which binds to this overload will invoke R-value constructors. Since std::map<K,V>::value_type
is std::pair<const key_type, mapped_type>
, and std::pair
has a constructor that takes R-values:
template<class U1, class U2>
pair(U1&& x, U2&& y);
then you are guaranteed that R-value constructors for key_type
and mapped_type
will be invoked, both in the creation of the pair
object, and in the map insertion, as long as you insert the pair using an expression that creates R-values, such as:
map1.insert(std::make_pair(0, Huge());
OR
map1.insert(std::make_pair(0, std::move(huge1));
Of course, all of this is dependent on Huge
having a proper R-value constructor:
Huge(Huge&& h)
{
...
}
Finally, you can also use std::map::emplace
if you simply want to construct a new Huge
object as an element in the map.
You could do that (the {0,std::move(huge1)}
part). But you could also skip the middleman (assuming you're constructing the objects within the function) like this:
map1.emplace(std::piecewise_construct, 0, std::forward_as_tuple(some, args));
map2.emplace(std::piecewise_construct, std::forward_as_tuple(some, args), 0);
Or, if your function is given the objects, you can still use emplace
:
map1.emplace(0, std::move(huge1));
map2.emplace(std::move(huge1), 0);
An alternative that avoids both copying and moving would be to use std::map::emplace()
. From the linked reference page:
Inserts a new element to the container. The element is constructed in-place, i.e. no copy or move operations are performed. The constructor of the element type (value_type, that is, std::pair) is called with exactly the same arguments as supplied to the function, forwarded with std::forward(args)....
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With