Is it safe to use const reference to returned rvalue in doSomething?
Yes, this is perfectly fine. The language has an specific clause that guarantees that if you bind a reference to an rvalue a temporary is created and the lifetime is extended until the end of the scope where the reference is created.
Does doSomething2 create a copy of returned rvalue, is compiler allowed to do rvalue optimization here?
In both cases the cost is the same, as the compiler will do RVO (return value optimization)
what are the differences between doSomething and doSomething2 and which one is prefferable?
The main difference is that in one case you are giving a name to the real object and in the other case the name is given to a reference. The compiler should generate exactly the same code in both versions.
That being said, I find the use of the const&
to be misleading. It gives the impression that the local function has a reference to some object somewhere, but it really has a copy (with no name). To realize that this is a copy the maintainer will have to look and verify the signature of the function that is being called. In the case of the value the behavior is more obvious: the function maintains a copy of whatever is returned by the function (which might be a value or reference).
The second difference is that you are only legally allowed to bind a const reference, which means that the function cannot modify the object. In the case of storing a value, the type can be non-const and the function could modify that object, so the approach is more flexible.
In C++03 the only reason to use the const& trick is in the case where you know that the function returns a value, you know that the type derives from a well known base, and you don't want to name the type [Take a look at ScopeGuard]. In C++11 that use is no longer important, as you can just use auto
to let the compiler figure out the type automatically.