Search code examples
c++c++11referencelifetimeconst-reference

Reference for rvalue or not


I wonder will next code work correct with v and v2 variable or these are references for temporary variables? In other words, can I capture returned rvalue by reference? I think no, but my teamlead think another way.

#include <iostream>

struct Foo {
  Foo(Foo&&) = delete;
  Foo& operator=(Foo&&) = delete;

  Foo() {
    std::cout << "Constructor" <<std::endl;
  }
  Foo(const Foo&) {
    std::cout << "Copy Constructor" <<std::endl;
  }
  Foo& operator=(const Foo&) {
    std::cout << "Copy  = Constructor" <<std::endl;
    return *this;
  }
  ~Foo() {
    std::cout << "Destructor" <<std::endl;
  }
};

Foo foo() {
  Foo v;
  return v;
}

int main() {
  const auto& v = foo();
  const auto& v2 = v;
  return 0;
}

Solution

  • Yes, this works fine and its behavior is defined.

    const auto& v = foo();
    

    This binds a temporary to a reference. The lifetime of the temporary will be extended to match the lifetime of v. (Binding temporaries to const references was supported in C++03 even, before rvalue references were a thing.)

    const auto& v2 = v;
    

    This just takes another reference to the same object. It's basically a no-op that will be eliminated during compilation. As long as v2 doesn't outlive v (which it doesn't in this case) then there is no problem.