You need to return as a link if you want the opening end to have access to the specified object. Consider operator[] in the map and use case:
std::map<std::string, int> word_count; std::string word; while ( std::cin >> word ) { word_count[ word ]++; }
You do not want to extract the value from the map, but rather access the saved object in this case to change it. The same thing happens with many other projects where you need access to some internal data, but you do not want to copy it:
if ( person.name() == "Pete" ) {
The user does not need to copy the object, only to check whether the object has a specific value. You could force the copy to return by value, and the semantics would be the same, but at a higher cost. Or you can create a local variable and pass it by reference to a function that will fill it, and in this case you will not only bear the cost of copying, but also make the code more cumbersome:
std::string name; person.fill_name( name ); if ( name == "Pete" ) {
Which, as you probably notice, is much more cumbersome in all applications of a member function.
Now I see that “I ask for this with functions other than members”, well, the same reasoning applies at different levels. Free constant functions can be applied to objects, consider:
boost::any any = 5; boost::any_cast<int&>( any )++;
The any_cast function is a free function, and yet it returns a link to another instance. If you need access to the actual object, not the copy, then the link is the solution. Please note that you do not need a link to read, and you can also return by value:
std::cout << boost::any_cast<int>( any );
Similarly, in all cases when a function returns references to objects that are not arguments, but globals or static (returning a reference to a variable with automatic storage in a function is undefined behavior, but in all cases when it does it correctly, the semantics will not the same if you change it to any other solution.