Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11: Is using std::move only safe on temporary objects?

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?

like image 790
bombax Avatar asked Aug 26 '15 21:08

bombax


People also ask

Is std :: move 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.

When should we use std :: move?

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.

What does move () do in C ++?

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.

What happens to object after std :: move?

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.


1 Answers

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.

like image 174
Benjamin Lindley Avatar answered Sep 21 '22 15:09

Benjamin Lindley