lundi 12 août 2019

Why isn't the r-value lifetime extended by the r-value reference? [duplicate]

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)

Aucun commentaire:

Enregistrer un commentaire