I am implementing some classes to represent mappings (in the mathematical sense), i.e., f : R x R^n -> R^n. I would like to implement an abstract base class that either:
1) Takes a std::array as a reference and modifies it
or
2) returns a std::array (by value or by reference, not sure?)
The syntax of option 2 is more desirable to me simply because I think the code will look more like the math I’m trying to represent, but I want to make sure I am not needlessly copying things and inducing a bunch of undesired overhead. For example, if I had:
// Function f declaration
std::array<double, 4> f(double t, const std::array<double, 4> & x);
// Some code snippet that uses f
std::array<double, 4> x = {0.0, 1.0, 2.0, 3.0};
double t = 0.0;
std::array<double, 4> dxdt = f(t, x);
How can I determine whether a copy is being performed on the last line, or how can I ensure that it doesn’t happen?
Within the definition of f(), what would I need to do (if anything) to ensure that this is returned without a call to the copy constructor? I want to keep the usage simple so clients don’t need to use pointers or smart pointers, but maybe this is necessary?
I know I can change this to return void and just make one of the arguments be std::array dxdt, but I like the return value syntax better, as long as there is no performance penalties or memory leak issues.
It should be something you shouldn’t care, since optimizing copies is a compiler problem. But compilers are still Turing-based machines that cannot invent optimization themselves.
As far I know most of today’s compilers behave, if a function:
The compiler allocates that variable on the stack in the place it has to be to be evaluated by the expression the function call belongs.
No copy are generated for that.
If your function have multiple exits returning different expressions this -apart some particular cases- cannot be done.
So, in general, if you have to return some wide object, just declare it and make sure all the return statements return just it.