heretoinfinity
heretoinfinity

Reputation: 1746

Where is the rvalue coming from?

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:

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

Answers (1)

songyuanyao
songyuanyao

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 floats directly. They have to be converted to doubles 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

Related Questions