5.8.  Returning References from Functions

[ fromfile: functions.xml id: referencereturns ]

Sometimes it can be useful to design a function so that it returns a reference. For example, This makes it possible to chain operations like this:

  cout << thing1 << thing2 << thing3 ... ;

A reference return (especially of *this) is used to provide lvalue behavior for member functions.

As with reference parameters, it is possible to protect a reference return by specifying that the object it aliases is const.

Example 5.15 captures the essence of reference returns.

Example 5.15. src/reference/maxi.cpp

#include <iostream>
using namespace std;
int& maxi(int& x, int& y) { 

    return (x > y) ? x : y;
}

int main() {
    int a = 10, b = 20;
    maxi(a,b) = 5;      1
    maxi(a,b) += 6;     2
    ++maxi(a, b) ;      3
    cout << a << '\t' << b << endl;
    return 0;
}
Output:

17      5


1

Assigns the value 5 to b.

2

Increases a by 6. a is now 16.

3

Increments a by 1.


As you see in the main() function, the reference return value of the function maxi() makes the expression maxi(a,b) into a modifiable lvalue.

[Warning] Caution

Be careful that your function does not return a reference to a temporary (local) object. A moment's thought should make the reason for that restriction clear: When the function returns, its local variables are all destroyed.

int& max(int i,int j) {
    int retval = i > j ? i : j;
    
    return retval;
}

If you are lucky, code like the preceding code may generate a compiler warning, but (alas) the compiler does not consider it an error. Here is the warning that a recent version of g++ gives.

 badmax.cpp:4: warning: reference to local variable 'retval' returned

A more practical example showing the benefits of reference returns is shown in Example 5.16, which defines some common operators for vectors.