0

In C++ it is possible to pass an rvalue to a function accepting a const lvalue reference. I don't understand why this is.

The expression Function(Entity()) is ostensibly an rvalue, it has no identifiable location in memory. If Function() were to take an Entity& rather than a const Entity&, then this would not work. But if the function takes a const lvalue reference rather than an lvalue reference, then this works fine.

Could someone please provide an explanation for how this works and why?

class Entity
{
   Entity()
   {
      std::cout << "Entity created\n";
   }
}

void Function(const Entity& e) // recieved as const lvalue reference
{
   std::cout "Inside function\n";
}

int main()
{
   Function(Entity()); // passing rvalue
}
Ryan Walter
  • 229
  • 1
  • 10
  • This has more to do with [the lifetime of temporaries](https://en.cppreference.com/w/cpp/language/reference_initialization#Lifetime_of_a_temporary) than about rvalue and lvalues. – Some programmer dude Sep 23 '19 at 12:14
  • Check out [here](https://en.cppreference.com/w/cpp/language/lifetime#Temporary_object_lifetime) – Thomas Lang Sep 23 '19 at 12:14
  • All temporaries have a location in memory, but C++ doesn't always expose that location :) – Pubby Sep 23 '19 at 12:14
  • Also note that technically there's nothing that stops a compiler from binding a temporary object to a non-constant lvalue-reference, as shown by the Visual C++ extension that does just that. It's really a limitation in the C++ specification to make lifetime (and other) issues easier to handle. – Some programmer dude Sep 23 '19 at 12:16

1 Answers1

1

It's important to note is that this does not require classes. void Function(int const& i) { std::cout << i; } can be called as Function(2+2).

The reason is the same for classes and built-in types alike. A temporary can bind to const references. This is very intentional. It's safe and useful. Safe: Since you can't change the referenced object through a const reference, there is no chance of such a change getting lost in a temporary object. Useful: it saves the compiler from making copies of big objects.

MSalters
  • 173,980
  • 10
  • 155
  • 350