For the following code, I understand why in the first example, the temporary has its lifetime extended, but not why this lifetime extension doesn't happen in the second example:
#include <iostream>
struct A
{
A() { std::cout << "construct A:" << this << "\n"; }
~A() { std::cout << "destruct A:" << this << "\n"; }
A & operator () (int i) & { std::cout << "int&" << this << "\n"; return *this; }
A && operator () (int i) && { std::cout << "int&&:" << this << "\n"; return std::move(*this); }
};
int main()
{
{
std::cout << "\nNOT DANGLING...\n";
A && a = A()/*(32)(42)*/;
std::cout << "using...\n";
a(52)(62); // OK: No dangling reference
} // NORMAL: Temporary destroyed at end of scope
{
std::cout << "\nDANGLING...\n";
A && a = A()(32)(42); // PROBLEM: Temporary immediately destroyed
std::cout << "using...\n";
a(52)(62); // ERROR: Dangling reference
}
return 0;
}
The output of Compiler Explorer is:
NOT DANGLING...
construct A:0x7ffc7b1f08fe
using...
int&0x7ffc7b1f08fe
int&0x7ffc7b1f08fe
destruct A:0x7ffc7b1f08fe
DANGLING...
construct A:0x7ffc7b1f08ff
int&&0x7ffc7b1f08ff
int&&0x7ffc7b1f08ff
destruct A:0x7ffc7b1f08ff
using...
int&0x7ffc7b1f08ff
int&0x7ffc7b1f08ff
Why, in the second example, is the temporary immediately destroyed, and I'm left with a dangling pointer?
(Note: this happens on GCC and Visual Studio, with C++11 or C++17)