C++0x Overload on reference, versus sole pass-by-value + std::move?
- by dean
It seems the main advice concerning C++0x's rvalues is to add move constructors and move operators to your classes, until compilers default-implement them.
But waiting is a losing strategy if you use VC10, because automatic generation probably won't be here until VC10 SP1, or in worst case, VC11. Likely, the wait for this will be measured in years.
Here lies my problem. Writing all this duplicate code is not fun. And it's unpleasant to look at. But this is a burden well received, for those classes deemed slow. Not so for the hundreds, if not thousands, of smaller classes.
::sighs:: C++0x was supposed to let me write less code, not more!
And then I had a thought. Shared by many, I would guess.
Why not just pass everything by value? Won't std::move + copy elision make this nearly optimal?
Example 1 - Typical Pre-0x constructor
OurClass::OurClass(const SomeClass& obj) : obj(obj) {}
SomeClass o;
OurClass(o); // single copy
OurClass(std::move(o)); // single copy
OurClass(SomeClass()); // single copy
Cons: A wasted copy for rvalues.
Example 2 - Recommended C++0x?
OurClass::OurClass(const SomeClass& obj) : obj(obj) {}
OurClass::OurClass(SomeClass&& obj) : obj(std::move(obj)) {}
SomeClass o;
OurClass(o); // single copy
OurClass(std::move(o)); // zero copies, one move
OurClass(SomeClass()); // zero copies, one move
Pros: Presumably the fastest.
Cons: Lots of code!
Example 3 - Pass-by-value + std::move
OurClass::OurClass(SomeClass obj) : obj(std::move(obj)) {}
SomeClass o;
OurClass(o); // single copy, one move
OurClass(std::move(o)); // zero copies, two moves
OurClass(SomeClass()); // zero copies, one move
Pros: No additional code.
Cons: A wasted move in cases 1 & 2. Performance will suffer greatly if SomeClass has no move constructor.
What do you think? Is this correct? Is the incurred move a generally acceptable loss when compared to the benefit of code reduction?