In the old days we were trained to use result parameters passed by reference in order to avoid unnecessarily copying data around.
However with smarter compilers - and particular the extensions to C++11 is this still required?
Specifically, is there any reason in 2018 with modern C++11/C++14 compilers to (still) use
void Filter(vector<CObject*> &elements, vector<CObject*> &outElements);
instead of simply returning the vector, i.e.
vector<CObject*> Filter(vector<CObject*> &elements);
Thanks in advance for all insights!
Passing by reference saves a lot of time and makes the implementation of the code faster. Note: If we do not want a function to modify a vector, we can pass it as a const reference also.
vector<int> is non-array, non-reference, and non-pointer - it is being passed by value, and hence it will call copy-constructor. So, you must use vector<int>& (preferably with const , if function isn't modifying it) to pass it as a reference.
Yes, returning a reference to an element of a std::vector is safe, unless you change the number of elements in the container while holding on to the reference.
Returning the object should be used in most cases because of an optimsation called copy elision. However, depending on how your function is intended to be used, it may be better to pass the object by reference.
and particular the extensions to C++11 is this still required?
No. In the best case scenario, RVO (return value optimization) will kick in, which will completely elide any copy/move.
In the worst case scenario, the object will be moved out of the function. Moves for std::vector
are very cheap (comparable to just a few pointer swaps).
This is because the expression Filter(some_input)
is an rvalue of type std::vector<CObject*>
, and std::vector
's constructor has an overload accepting an rvalue reference: see (6) here.
In the old days we were trained to use result parameters passed by reference in order to avoid unnecessarily copying data around.
Actually, even when one was using an old C++ compiler this was pretty poor advice: write for clarity first and efficiency second.
In particular, returning by a reference value prevents making the values in the caller const
(which improves clarity and provides other optimization opportunity).
Of course, if profiling shows this was a performance bottleneck, then one had to make the necessary changes. With RVO and NRVO (which are now pretty common), and move semantics as a back-up it is now very unlikely to be a performance bottleneck.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With