It is my understanding that the current (post-C++11) convention is to write setters with movable types as follows:
void set_a(A a) {
a_ = std::move(a);
}
What is the best way to write another setter or forwarder function that calls this set_a()? For example:
void set_ab(A a, B b) {
set_a(std::move(a)); // like this?
set_b(b); // or like this?
}
Or:
void do_one(A a) { // by value? by const ref? by rvalue-ref?
do_two(a); // move?
}
void do_two(A a) {
obj.set_a(a);
}
I don't think std::move() is appropriate here, so how should I write this for efficiency, assuming an optimizing compiler?
Do all these function signatures depend on whether I'm storing the final A object somewhere or not?
Thanks
When you have a value you are not going to reuse, std::move
it.
When you have an rvalue reference you are not going to reuse, std::move
it.
When a forwarding reference, std::forward
it if and only if you'd move it if it was an rvalue reference.
The rule to take by value presumes:
You don't mind silently making a copy at the call site
Moving is so cheap you treat it as free
Copying is much more expensive than moving
If (1) is false, instead take an rvalue reference (A&&
) in your sink parameter. Now callers have to explicitly make their copy.
If (2) is false, perfect forwarding, multiple overloads, type-erased emplacing, or a myriad of other more complex solutions should be used.
If (3) is false, don't bother with move
ing. Just take by value.
If all 3 are true, then your set_ab
looks like:
void set_ab(A a, B b) {
set_a(std::move(a));
set_b(std::move(b));
}