C++中调用接收double&参数的函数传入float变量时,右值(rvalue)的来源及报错底层原理问询
float to a double& Parameter Great question—let’s break this down step by step to clear up every part of your confusion.
Where does the rvalue come from?
When you pass your float variables a and b to a function expecting double& parameters, C++ has to perform an implicit type conversion: it converts the float values to double. But this conversion can’t modify your original float variables (they’re a different type, after all), so instead, the compiler creates a temporary double object to hold the converted value.
In C++, temporary objects are classified as rvalues—they’re short-lived, can’t be assigned to, and non-const lvalue references (like double&) aren’t allowed to bind to them. That’s exactly what your error message is complaining about.
Is the rvalue the temporary double from the float conversion, or the literal 55.5?
It’s definitely the temporary double from the float-to-double conversion. The error points directly to the arguments a and b in your function call, not the 55.5 literal in the assert check. That literal is a double by default, and comparing it to your function’s return value (a double) is totally valid—no issues there.
Does the return type matter here?
You’re spot-on: the return type has nothing to do with this error. Your function returns a double by value, which does produce an rvalue, but comparing that to the 55.5 literal is a legal operation. The problem occurs when you call the function, not when you use its return value.
Why does it work with double variables?
When a and b are double types, they’re lvalues—they’re named variables you can take the address of and modify. A double& reference can bind directly to a same-type lvalue without any conversion, so no temporary rvalue is created. That’s why the compiler doesn’t complain in this case.
Quick fixes (if you ever need to support floats)
If you wanted this function to work with float variables without changing their type, you have a few options:
- Change the parameters to
const double&: Const lvalue references are allowed to bind to rvalues (including temporary objects), though this would prevent you from modifying the input variables. - Overload the function: Write a separate version that takes
float¶meters. - Use a template: Make the function generic so it works with any numeric type, like:
template<typename T> T referenceToDouble(T& left, T& right) { if (left >= right) { right = left; } else { left = right; } return left; }
内容的提问来源于stack exchange,提问作者heretoinfinity

