I have read in some others posts that move
is unnecessary and even deoptimizes mechanisms like NRVO. But it was in most cases about a local field.
Consider this example:
In this case, is it appropriate to use std::move
on return
?
Specifically, are these pieces of code equivalent?
The second is more "generic", letting the user decide if the result should be moved or not, and the first one is more strict — any call will consume the result.
// Option 1
#include <utility>
template<typename T>
class TemporaryResultHolder
{
public:
void doTask() { result = T(); }
T getResult() { return std::move(result); }
// Or return T&& ?
private:
T result;
};
int main() {
TemporaryResultHolder<int> holder;
holder.doTask();
int res = holder.getResult();
return 0;
}
// Option 2
#include <utility>
template<typename T>
class TemporaryResultHolder
{
public:
void doTask() { result = T(); }
T getResult() { return result; }
private:
T result;
};
int main() {
TemporaryResultHolder<int> holder;
holder.doTask();
int res = std::move(holder.getResult());
return 0;
}
If you were to return an object with automatic storage, then you should never return with std::move
because former is faster in best case, and equal in worst case.
I have read in some others posts that it's unecessarily and even deoptimize mecanisms like NRVO.
And this is the reason. This doesn't however apply to the function in the question, because it doesn't return an object with automatic storage, but rather a member variable. NRVO cannot apply to a member variable, nor does the implicit move of return value.
So, in your example, return std::move(result);
does a move, and return result;
does a copy. You should use move if the purpose of the function is to move from the member, and copy if the purpose is to copy the member. Note however that moving from a member in a function that is not rvalue qualified is quite unconventional design, and I recommend to avoid it unless you have a good reason to do so. Also note that the copying version can be const qualified, which would make it more generally useful.
P.S. for int
that is used in the example, these distinctions are irrelevant. Moving versus coping is only relevant to non-trivially copyable / -movable types.
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