Reputation: 1746
I learning about references and value categories because the latter are mentioned in some C++ errors.
I have a function, referenceToDouble
that takes in references to double. From watching this video on value categories, I believe that left
and right
below are lvalue references to double.
In main
when I make variables a
and b
of type double
, I don't get an error. Code below shows a
and b
of type float
which gives me an error.
#include <cassert>
double referenceToDouble(double& left, double& right) {
if (left >= right) {
right = left;
}
else {
left = right;
}
return left;
}
int main() {
float a = 55.5;
float b = 55.5;
assert(55.5 == referenceToDouble(a, b));
}
When I switch the data type of a
and b
to float
, I get this error.
checkReferences.cpp: In function 'int main()':
checkReferences.cpp:18:35: error: cannot bind non-const lvalue reference of type 'double&' to an rvalue of type 'double'
18 | assert(55.5 == referenceToDouble(a, b));
| ^
checkReferences.cpp:3:34: note: initializing argument 1 of 'double referenceToDouble(double&, double&)'
3 | double referenceToDouble(double& left, double& right) {
| ~~~~~~~~^~~~
My questions are:
where is the rvalue coming from?
Is there a temporary variable that contains the double
value of a
that was cast from float
? And is this temporary then the rvalue
?
Or is the error referring to the 55.5
which is a literal and
therefore an rvalue?
Is the return type not involved here? I think it isn't because this is a return by value and not by reference.
I tried reading the answer to this question that had a similar error but I wasn't able to dispel my doubts. I also think I know what the solution (use double
) is but I am trying to understanding what is going on under the hood.
Upvotes: 3
Views: 122
Reputation: 172924
Is there a temporary variable that contains the double value of a that was cast from float? And is this temporary then the rvalue?
Yes. left
and right
with type double&
can't bind to float
s directly. They have to be converted to double
s firstly, which are temporaries (rvalues) and can't be bound to lvalue-reference to non-const.
If you change the type of left
and right
to const double&
then it'll work fine. The converted double
temporaries (rvalues) could be bound to lvalue-reference to const
.
Upvotes: 2