Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is temporary lifetime extension useful in modern C++?

In C++ you can bind return value of a function (which return value, not reference) to const reference and code will still be valid because lifetime of this temporary will be prolonged till the end of scope. For example

std::string get_string() {
    return "abc";
}


void f() {
    const std::string& str = get_string();
    std::cout << str; // valid, str is not dangling reference.
}

My question is, when is it useful, e.g. when is code like

A get_a();
const A& a = get_a();

better than the code

A get_a();
A a = get_a();

and in what way (e.g. faster, smaller binary size, etc)? What should be the implementations of A, get_a and code after calling get_a?

I've tested several cases by hand and in each case it seems to have the same number of copies and moves.

Let's restrict this question to current C++ standard, modern versions of compilers and builds with optimisation enabled (O2, O3 or equivalents for other compilers)

like image 915
RiaD Avatar asked Jun 04 '18 04:06

RiaD


1 Answers

Deliberate lifetime extension of prvalues into named stack variables like this is not useful if you know exactly what's going on. Which means it is useful if you don't know exactly what's going on.

Say, you're in a template function. And the user is supposed to give you some object that has a get member function that returns some type that fits some expected behavior. Question: does get return a reference or a prvalue?

Answer: you don't care. It doesn't matter if it returns a prvalue or a reference; what matters is that what it returns can be manipulated in the fashion you expect. So you might expect obj.get() = 10; to work, for example.

Maybe get returns a reference to an object. Or maybe it returns a prvalue that is a proxy object that acts like a reference. In the above case, maybe it has an operator= overload, so that you can assign to it. You the user don't care.

So, what happens if you want to store what get returns for a (short) period of time? Well, you don't want to do auto x = obj.get();; if it returned an actual reference, you would get a copy of the reference, which is probably not what you wanted. So you do auto &&x = obj.get();. Lifetime extension allows this to work just as well with proxy prvalue objects as with actual references.

like image 111
Nicol Bolas Avatar answered Sep 22 '22 11:09

Nicol Bolas