This question already has an answer here:
Assume I have the following class, which has a method set_value
. Which implementation is better?
class S {
public:
// a set_value method
private:
Some_type value;
};
Pass by value, then move
void S::set_value(Some_type value)
{
this->value = std::move(value);
}
Define two overloaded methods
void S::set_value(const Some_type& value)
{
this->value = value;
}
void S::set_value(Some_type&& value)
{
this->value = std::move(value);
}
The first approach requires definition of one method only while the second requires two.
However, the first approach seems to be less efficient:
- Copy/Move constructor for the parameter depending on the argument passed
- Move assignment
- Destructor for the parameter
While for the second approach, only one assignment operation is performed.
- Copy/Move assignment depending on which overloaded method is called
So, which implementation is better? Or does it matter at all?
And one more question: Is the following code equivalent to the two overloaded methods in the second approach?
template <class T>
void S::set_value(T&& value)
{
this->value = std::forward<T>(value);
}
The compiler is free to elide (optimise away) the copy even if there would be side effects in doing so. As a result, passing by value and moving the result actually gives you all of the performance benefits of the two-method solution while giving you only one code path to maintain. You should absolutely prefer to pass by value.
here's an example to prove it:
expected output:
note the absence of any redundant copies in the copy/move versions but the redundant copy-assignment when calling
set_value_by_const_ref()
with nameless temporary. I note the apparent efficiency gain of the final case. I would argue that (a) it's a corner case in reality and (b) the optimiser can take care of it.my command line: