If I have a class implementing move semantics:
class BigObject
{
public:
BigObject(something x = something()) { ... }
BigObject(const BigObject& other) { ... }
BigObject(BigObject&& other) { ... }
BigObject& operator=(BigObject other) { ... }
void swap(BigObject& other) { ... }
// [...]
};
auto begin = std::begin(somethingSequence); // collection doesn't matter here
auto end = std::end(somethingSequence); // collection doesn't matter here
BigObjectOutputIterator dest; // collection doesn't matter here
What is the correct way to do return a BigObject in a lambda?
std::transform(begin, end, dest,
[](something x) -> BigObject {return BigObject(x); });
or
std::transform(begin, end, dest,
[](something x) -> BigObject&& {return std::move(BigObject(x)); });
or
std::transform(begin, end, dest,
[](something x) -> BigObject {return std::move(BigObject(x)); });
or some other form?
Thanks.
The first and third form are basically the same, since return BigObject(x); is an rvalue and as such the move constructor is called already.
The second form however invokes undefined behaviour, as an rvalue reference is still just a reference, and a reference to something that goes out of scope is still as bad as it was before.
The first form is just fine. As a general rule, never, ever, return rvalue references. The third form doesn't need the move, as BigObject(x) is already an rvalue.
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