1
votes

§12.2/5 (my emphasis)

The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:

  • A temporary bound to a reference ...
  • A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full-expression containing the call.

In the snippet below (live example) one can see that the temporary A() is bound to the reference a for the lifetime of the reference, that is, the destructor ~A() is invoked at the end of the function f.

#include <iostream>

struct A{
    A() { std::cout << "A()" << '\n'; }
    ~A() { std::cout << "~A()" << '\n'; }
};

void f(A&& a) { std::cout << "f()" << '\n'; }

int main()
{
    f(A());
}
1
In your example, the function call is the full-expression, so your example doesn't really demonstrate anything.Mat

1 Answers

3
votes

Consider this absurd example:

#include <iostream>

struct A {
    void bar() { std::cout << "bar [" << i << "]" << std::endl; }
    ~A() { std::cout << "dtor" << std::endl; }

    int i;
};

A& foo(A&& a) { return a; }

int main()
{
    foo(A{4}).bar();
}

If the lifetime of the temporary wasn't extended to the completion of the full-expression, .bar() would be called on an already-destroyed object, since the lifetime of a ends when foo is complete. As is, this will print:

bar [4]
dtor