const reference to a temporary object becomes broken after function scope (life time)

后端 未结 2 1173
难免孤独
难免孤独 2020-12-03 16:21

While asking this question, I learned const reference to a temporary object is valid in C++:

int main ()
{
  int a = 21;
  int b = 21;

  //error: invalid in         


        
2条回答
  •  眼角桃花
    2020-12-03 16:44

    My original example is complex.

    Therefore I post here a simpler example and I provide the corresponding ISO C++ standard paragraph.

    This simpler example is also available on coliru.stacked-crooked.com/

    #include 
    
    struct A
    {
      A(int i) { std::cout<<"Cstr "<< i<<'\n'; p = new int(i); }
     ~A()      { std::cout<<"Dstr "<<*p<<'\n'; delete p;       }
    
      const A& thiz() const { return *this; }
    
      int *p;
    };
    
    const A& constref( const A& a )
    {
      return a;
    }
    
    int main()
    {
      const A& a4 = A(4);
      const A& a5 = A(5).thiz();
      const A& a6 = constref( A(6) );
    
      std::cout << "a4 = "<< *a4.p <<'\n';
      std::cout << "a5 = "<< *a5.p <<'\n';
      std::cout << "a6 = "<< *a6.p <<'\n';
    }
    

    The output using command line g++-4.8 -std=c++11 -O2 -Wall -pedantic -pthread main.cpp && ./a.out:

    Cstr 4
    Cstr 5
    Dstr 5
    Cstr 6
    Dstr 6
    a4 = 4
    a5 = 0
    a6 = 0
    Dstr 4
    

    As you can see, the temporary objects referenced by a5 and a6 are destructed at the end of functions thiz and constref respectively.

    This is an extract of §12.2 Temporary objects, where the bold part applies in this case:

    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 member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits.
    • 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.
    • The lifetime of a temporary bound to the returned value in a function return statement (6.6.3) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.
    • A temporary bound to a reference in a new-initializer (5.3.4) persists until the completion of the full-expression containing the new-initializer.

    This is a more complete example:

    #include 
    
    struct A
    {
         A()         { std::cout<<"Cstr 9\n";         p = new int(v = 9);      }
         A(int i)    { std::cout<<"Cstr "<
                                                            
提交回复
热议问题