So, I have the following class:
class Foo {
public:
Bar &&bar() {
return std::move(_bar);
}
private:
Bar _bar;
}
I know that it is valid to use this class in the following context:
Bar bar;
{
Foo foo;
bar = foo.bar(); // bar is move-assigned, as foo is still in scope
}
Now, the situation I an wondering about is: what happens if I directly return bar from a method, without storing it beforehand:
Bar testFunc() {
Foo foo;
return foo.bar();
}
Bar test = testFunc();
// is test now valid?
I think that this should be theoretically fine, as testFunc
returns a value that is constructed from the rvalue before foo
is destroyed - but is this still the case if the compiler applies return-value-optimization?
I guess I am a little confused how exactly this works...
is test now valid?
The code should be valid as long as the moved-from object is not accessed.
but is this still the case if the compiler applies return-value-optimization?
Bar testFunc() {
Foo foo; // Bar is constructed here
return foo.bar(); // prvalue is move-constructed and copy elided
}
Bar test = testFunc(); // default ctor + move ctor (one copy elision)
In total one copy elision is performed.
Moving out a member seems like a code smell. It is hard to judge without knowing the concrete usage, but maybe:
Bar make_bar(const Foo& foo) {
Bar bar;
// init bar as needed
return bar;
}
This way both calls will result in RVOs.