I want freeFunct to do non const stuff on its own copy of object a.
Let's say that freeFunct is required to be a free function because in real code cases it takes many different parameters, calls several public functions from all of them and there is no point in making it a non-static member function of any class.
Three different ways of declaring it come to my mind.
I have the feeling that the third solution is the worse.
Is there any difference between the first two?
Is there something better?
void freeFunct1(A a){
a.doStuff();
}
void freeFunct2(const A& a){
A b = a;
b.doStuff();
}
/**users of freeFunct3 are expected
*to give a copy of their variable:
*{
* A b = a;
* freeFunct3(b);
*}
*/
void freeFunct3(A& a){
a.doStuff();
}
First, as already said, don't do
freeFunct3
if the semantics of the free function is to only modify its "own" object.Second, there are differences between
freeFunct1
andfreeFunct2
, relating to move optimization [C++11], exception safety, and potentially code size.With
freeFunct2
(taking by reference-to-const):A
throws an exception, it will throw inside the body of the function.A
's copy constructor is inlined (and the function is not), it will be expanded once, inside the body of the function (even if the function is called from multiple different places).With
freeFunct1
(taking by value):A
has a move constructor and you pass an rvalue (e.g. callfreeFunct1(A(args))
).A
throws an exception, it will throw at the call site.A
's copy (or move) constructor is inlined, it will be expanded multiple times, at each call site.Alternatively, you can overload on lvalue/rvalue reference to avoid unnecessarily copying rvalues: