I asked this question: static_assert of const Variable
And apparently it comes down to the question does a floating point lvalue get converted to an rvalue for the purposes of comparison?
So in this code does an lvalue-to-rvalue conversion occur?
const float foo = 13.0F;
static_assert(foo > 0.0F, "foo must be greater than 0.");
Yes, it is performed. Basically, it's all because 3.0 > 1.2
is a well-formed expression, that contains nothing but prvalues for operands.
First, [expr]/9 states (emphasis mine) that
Whenever a glvalue expression appears as an operand of an operator that expects a prvalue for that operand, the lvalue-to-rvalue, array-to-pointer, or function-to-pointer standard conversions are applied to convert the expression to a prvalue.
So the question really boils down to "Do the relational operators expect prvalues for operands"? And the answer to that is also yes. For we need to consider [expr.rel]/1:
relational-expression: shift-expression relational-expression < shift-expression relational-expression > shift-expression relational-expression <= shift-expression relational-expression >= shift-expression
The operands shall have arithmetic, enumeration, or pointer type. The operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) all yield false or true. The type of the result is bool.
The above grammar production is the important bit. We can follow it (I won't do it entirely here) and reduce shift-expression
to a primary-expression
. And one of the productions of a primary-expression
is a literal
. For which it is said in [expr.prim.literal]:
A literal is a primary expression. Its type depends on its form. A string literal is an lvalue; all other literals are prvalues.
And because most literals are prvalues, I think it's safe to say the relational operators expect prvalues for operands.
来源:https://stackoverflow.com/questions/46980595/does-a-comparison-between-an-lvalue-and-a-literal-invoke-an-lvalue-to-rvalue-con