How come a non-const reference cannot bind to a temporary object?

前端 未结 11 1808
长情又很酷
长情又很酷 2020-11-21 05:19

Why is it not allowed to get non-const reference to a temporary object, which function getx() returns? Clearly, this is prohibited by C++ Standard but I am in

11条回答
  •  情深已故
    2020-11-21 05:22

    In your code getx() returns a temporary object, a so-called "rvalue". You can copy rvalues into objects (aka. variables) or bind them to to const references (which will extend their life-time until the end of the reference's life). You cannot bind rvalues to non-const references.

    This was a deliberate design decision in order to prevent users from accidentally modifying an object that is going to die at the end of the expression:

    g(getx()); // g() would modify an object without anyone being able to observe
    

    If you want to do this, you will have to either make a local copy or of the object first or bind it to a const reference:

    X x1 = getx();
    const X& x2 = getx(); // extend lifetime of temporary to lifetime of const reference
    
    g(x1); // fine
    g(x2); // can't bind a const reference to a non-const reference
    

    Note that the next C++ standard will include rvalue references. What you know as references is therefore becoming to be called "lvalue references". You will be allowed to bind rvalues to rvalue references and you can overload functions on "rvalue-ness":

    void g(X&);   // #1, takes an ordinary (lvalue) reference
    void g(X&&);  // #2, takes an rvalue reference
    
    X x; 
    g(x);      // calls #1
    g(getx()); // calls #2
    g(X());    // calls #2, too
    

    The idea behind rvalue references is that, since these objects are going to die anyway, you can take advantage of that knowledge and implement what's called "move semantics", a certain kind of optimization:

    class X {
      X(X&& rhs)
        : pimpl( rhs.pimpl ) // steal rhs' data...
      {
        rhs.pimpl = NULL; // ...and leave it empty, but deconstructible
      }
    
      data* pimpl; // you would use a smart ptr, of course
    };
    
    
    X x(getx()); // x will steal the rvalue's data, leaving the temporary object empty
    

提交回复
热议问题