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;
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With