Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this object considered an rvalue?

Tags:

c++

rvalue

Why is the object I'm passing to ClassA's constructor considered an rvalue (temporary)? I'm aware that setting the parameter to const will make the error go away but I want to understand what's going on.

This behavior works fine for a function call but not for a constructor?

#include <iostream>

using namespace std;

class ClassA {
public:
   ClassA() {}
   ClassA(ClassA&) {}
};

void f(ClassA&) {}

int main() {
   ClassA a;

   // Invalid initialization of non-const reference of type 'ClassA&' from an
   // rvalue of type 'ClassA'
   ClassA b = ClassA(a); 

   // Works fine
   f(a);

   return 0;
}
like image 317
Zhro Avatar asked Dec 24 '22 09:12

Zhro


1 Answers

The rvalue here is the ClassA(a) expression.

ClassA b = ClassA(a);

That is copy-initialization, so it will attempt to call the copy constructor of ClassA with the result of ClassA(a), which is an rvalue. You have declared the copy constructor to take a ClassA&, which can't bind to rvalues, so you get an error.

The best fix is, as you point out, to add const to the copy constructor so that it can bind to rvalues, but you could also use direct-initialization, or copy-initialization without the type conversion:

ClassA b (a);
ClassA b {a}; //C++11
ClassA b = a;

Note that although ClassA b = ClassA(a); requires a valid copy-constructor, the copy will likely be elided. This is currently optional, but may be made mandatory at some point.

like image 105
TartanLlama Avatar answered Dec 28 '22 10:12

TartanLlama