Roland Pibinger a écrit :
RVO is a hack! According to C++ semantics copying is performed.
According to this [1], it is said in the specification that
implementations may optimize it.
The first form is already optimized by old pre-standard C++ compilers
like MSVC6.
[1]
http://nkari.uw.hu/Tutorials/CPPTips/ret_val_opt
I actually searched it in the specification to be sure.
Unfortunetely I don't have the official one, so I used the current
working draft for the next version. (I probably wouldn't have the right
to paste the official anyway)
Here we go :
<bigquote>
When certain criteria are met, an implementation is allowed to omit the
copy construction of a class object, even if
the copy constructor and/or destructor for the object have side effects.
In such cases, the implementation treats the
source and target of the omitted copy operation as simply two different
ways of referring to the same object, and the
destruction of that object occurs at the later of the times when the two
objects would have been destroyed without the
optimization. This elision of copy operations is permitted in the
following circumstances (which may be combined
to eliminate multiple copies):
— in a return statement in a function with a class return type, when the
expression is the name of a non-volatile
automatic object with the same cv-unqualified type as the function
return type, the copy operation can be omitted
by constructing the automatic object directly into the function's return
value
— when a temporary class object that has not been bound to a reference
would be copied to a class object with
the same cv-unqualified type, the copy operation can be omitted by
constructing the temporary object directly into
the target of the omitted copy
[ Example:
class Thing {
public :
Thing ();
~ Thing ();
Thing ( const Thing &);
};
Thing f () {
Thing t;
return t;
}
Thing t2 = f();
Here the criteria for elision can be combined to eliminate two calls to
the copy constructor of class Thing: the copying
of the local automatic object t into the temporary object for the return
value of function f() and the copying of that
temporary object into object t2. Effectively, the construction of the
local object t can be viewed as directly initializing
the global object t2, and that object’s destruction will occur at
program exit. —end example ]
Probably most of them.
Unfortunetely I only own two C++ compilers, gcc and icc to test it out
(it was optimized for both of them)
You are free to test it with all the C++ compilers you have.
using some compiler switches
using no switch.
The switch is to disable the optimization.
under certain
non-portable circumstances
The code I gave is always optimized whatever the platform and the
circumstances are with the compilers that perform such optimizations.
I wouldn't call that an 'elegant C++ way'. Quite
the contrary.
It is elegant because it doesn't use pointers which should be avoided
whenever possible. (they're pure evil)