In my code, I have something like this:
unordered_multimap<string, unordered_map<string, string> > mEntities;
...
vector<unordered_map<string, string> > rawEntities;
if (qi::phrase_parse(&buf[0], (&buf[0]) + buf.size(), EntityParser<char*>(), qi::space, rawEntities)) {
for (auto &propGroup : rawEntities) {
auto search = propGroup.find("classname");
if (search != propGroup.end()) {
// is stealing propGroup safe???
mEntities.emplace(search->second, std::move(propGroup));
}
}
}
// rawEntities goes out of scope here
As you can see, I'm using std::move
on an object of type deduced to unordered_map<string, string>&
, which is obviously not unordered_map<string, string>&&
. Still, I know for sure that because rawEntities
goes out of scope after the for
loop, its elements (the string->string maps) will never be used again. So I'm figuring that it's safe to steal (move) its elements data because they won't be used again.
When I run the program, it seems to work. But is this bad practice / an anti-pattern, and particularly, does the standard guarantee it is safe?
tl;dr: Yes, this is safe, for several reasons. std::move is a cast to an rvalue-reference, which primarily changes which constructor/assignment operator overload is chosen. In your example the move-constructor is the default generated move-constructor, which just copies the ints over so nothing happens.
std::move is used to indicate that an object t may be "moved from", i.e. allowing the efficient transfer of resources from t to another object. In particular, std::move produces an xvalue expression that identifies its argument t . It is exactly equivalent to a static_cast to an rvalue reference type.
Move Constructor And Semantics: std::move() is a function used to convert an lvalue reference into the rvalue reference. Used to move the resources from a source object i.e. for efficient transfer of resources from one object to another.
std::move is actually just a request to move and if the type of the object has not a move constructor/assign-operator defined or generated the move operation will fall back to a copy.
On the contrary. Using std::move
on temporary objects is pointless. They're already R-values, and will be deduced as R-value references when passed to functions. The whole point of std::move
is to turn L-values into R-value references so they can be moved from.
So I'm figuring that it's safe to steal (move) its elements data because they won't be used again.
Yes, this is correct.
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