1

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;
}
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
voltento
  • 833
  • 10
  • 26
  • I mean... throw it in the compiler and see what it says? – cdhowie Jun 06 '18 at 15:29
  • It works correct, but for mee it seems v and v2 variable catch references for temporary value that mean lead to SEGFAULT – voltento Jun 06 '18 at 15:30
  • https://stackoverflow.com/questions/23063211/why-does-most-important-const-have-to-be-const – Mat Jun 06 '18 at 15:33
  • 2
    Binding a temporary to a const reference extends the lifetime of the temporary to the lifetime of the reference. – cdhowie Jun 06 '18 at 15:33

1 Answers1

3

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.

cdhowie
  • 158,093
  • 24
  • 286
  • 300