reference returning functions

Please explain, where we can use a reference returning function.
1
2
3
4
5
6
  int& setdate(int t)
{

return t;

}
A reference is an alias. An alternate name for the referred to object.

Ask yourself, what is the lifetime of object t?
When is it created?
When is it destroyed?

One can either create a copy (a new object) or refer to existing object.
Making a copy is cheap for simple objects.

Modifying a copy does not modify the original object.
A reference is valid only as long as the referred to object is valid.

There is also move semantics since C++11.


The function that you have posted should not return a reference. Not only does the reference lack any benefit, but the construct is dangerous.


In this code there are calls to functions that return a reference. Do you know where?
1
2
3
4
5
6
7
8
9
10
11
12
#include <vector>
#include <iostream>

int main() {
  std::vector<int> foo(7, 0);
  foo[0] = 42;

  for ( const auto & x : foo )
    std::cout << x << '\n';

  return 0;
}
A good example is vector::at(size_t i) which returns a reference to the i'th element in the vector or throws an exception if i is out of bounds.

A reference is valid only as long as the referred to object is valid.
...
The function that you have posted should not return a reference. Not only does the reference lack any benefit, but the construct is dangerous.

Just to be clear for the OP:
The returned reference in your example is invalid because "int t" is being passed by value, not by reference, and is therefore being copied to your setdate function.

In other words, int t is not the same variable that you passed to the setdate function; it is only a copy of it.
t only exists as a valid variable in memory for the duration of the function block. After the function ends, t is popped off the stack, and the reference to it becomes invalid.
Last edited on
The returned reference in your example is invalid because "int t" is being passed by value, not by reference, and is therefore being copied to your setdate function.

Passing the argument by reference is not a guarantee of correctness.

I was reminded of this example from a talk by Stephen T. Lavajev:
1
2
string&& join(string&& rv, const char* s) { return std::move(rv.append(s)); }
const string& r = join(temp(), "orary");

Which has the same problem: r always is left dangling, even though no copies are made. This is because the string prvalue bound to rv lives only until the semicolon on line 2.

This is wrong for the same reason, showing that the problem isn't specific to rvalue references:
1
2
const int& f(const int& x) { return x; } 
const int& x = f(42);

You can find a discussion of the first case here:
http://www.cplusplus.com/forum/general/219121/
Last edited on
Oh, interesting example. I didn't think of that, thank you.
Topic archived. No new replies allowed.