Вызывает ли сравнение между Lvalue и литералом преобразование Lvalue в Rvalue?
Я задал этот вопрос: static_assert из const Переменная
И, очевидно, это сводится к вопросу, преобразовывается ли lvalue с плавающей запятой в r для сравнения?
Итак, в этом коде происходит преобразование lvalue в rvalue?
const float foo = 13.0F;
static_assert(foo > 0.0F, "foo must be greater than 0.");
1 ответ
Да, это выполняется. В основном это все потому, что 3.0 > 1.2
является правильно сформированным выражением, которое содержит только значения для операндов.
Во-первых, [expr] / 9 утверждает (выделение мое), что
Всякий раз, когда выражение glvalue появляется в качестве операнда оператора, ожидающего значение prvalue для этого операнда, применяются стандартные преобразования lvalue-to-rvalue, array-to-pointer или function-to-pointer для преобразования выражения в prvalue.
Таким образом, вопрос сводится к следующему: "Ожидают ли реляционные операторы значения для операндов"? И ответ на это тоже да. Ибо нам нужно рассмотреть [expr.rel] / 1:
relational-expression: shift-expression relational-expression < shift-expression relational-expression > shift-expression relational-expression <= shift-expression relational-expression >= shift-expression
Операнды должны иметь арифметику, перечисление или тип указателя. Все операторы <(меньше чем),> (больше чем), <= (меньше или равно) и>= (больше или равно) все дают false или true. Тип результата - bool.
Вышеупомянутое производство грамматики - важный бит. Мы можем следить за этим (я не буду делать это полностью здесь) и уменьшить shift-expression
к primary-expression
, И одна из постановок primary-expression
это literal
, Для которого сказано в [expr.prim.literal]:
Литерал - это первичное выражение. Его тип зависит от его формы. Строковый литерал является lvalue; все остальные литералы являются значениями.
И поскольку большинство литералов являются значениями типа prvalue, я думаю, можно с уверенностью сказать, что реляционные операторы ожидают значения prvalue для операндов.