I came across a C++17 code base where functions always accept parameters by value, even if a const reference would work, and no semantic reason for passing by value is apparent. The code then explicitly uses a std::move
when calling functions. For instance:
A retrieveData(DataReader reader) // reader could be passed by const reference.
{
A a = { };
a.someField = reader.retrieveField(); // retrieveField is a const function.
return a;
}
auto someReader = constructDataReader();
auto data = retrieveData(std::move(someReader)); // Calls explicitly use move all the time.
Defining functions with value parameters by default and counting on move semantics like this seems like a bad practice, but is it? Is this really faster/better than simply passing lvalues by const reference, or perhaps creating a &&
overload for rvalues if needed?
I'm not sure how many copies modern compilers would do in the above example in case of a call without an explicit move on an lvalue, i.e. retrieveData(r)
.
I know a lot has been written on the subject of moving, but would really appreciate some clarification here.