Are there any articles about when it is a good practice to use const references as return types?
This is less of a question about a particular issue and more of an educative question.
We are in the process of migrating to modern C++ from a somewhat rudimentary level of C and me and my colleague are tasked with mentoring a group of other people on C++ since we are pretty comfortable with the language.
I am having a slight argument with said colleague about this subject. The example at hand is a simple class:
class Cls
{
private:
vector<int> vec;
public:
Cls() { /* put 3 random values in vec */ }
const vector<int>& getVec() {return vec; }
};
My argument from the fact that:
References should be used as returns since you don't lose time copy-ing stuff. It's straight-up speedup.
References should be const since if you return just a reference to vec
then anyone can mutate it using just the getter, which is obviously bad. Hence we need to return const TYPE&
for getters.
My colleague supports just returning vector<int>
and be done with it. His arguments are:
So my questions basically are:
Are there some articles about good practices on this subject and when to use const references instead of values as returns?
While me and my colleague are fairly comfortable with C++ neither of us has worked professionally with it so... is there a standard or convention in the industry for this question?
The decision of when to return by-reference vs. by-value is not just a matter of performance, it's a matter of code semantics (although performance usually matters a lot when coding in C++).
Some notable examples of returning by-reference are:
*this
)The question of when to return by-reference actually boils down to a broader question of how to manage object's lifetime safely. C++ Core Guidelines on object's lifetimes is a good resource to adhere to.
If the object being referred-to outlives the function invocation, then it's generally safe to return it by-reference.
So:
this
, class members and objects with static storage duration: safe to return it by-reference
locals and function's input arguments: not safe to return by-reference. For input arguments, it applies even to const
-references, since they can refer to temporaries. For example:
std::string const& badFunc(std::string const& arg) {
return arg; // not a good idea
}
int main() {
std::string const& x = badFunc("abc");
// now x contains a dangling reference!
// ...
}