В чем причина именования «lvalue» и «rvalue» в C / C ++ (я знаю, как они функционируют)?
Стандарт упоминает это:
Lvalue (исторически так называемый, потому что lvalue может появляться в левой части выражения присваивания) […]
Значение r (исторически так называемое, потому что значения могут появляться в правой части выражения присваивания) […]
То есть lvalue — это то, что вы можете назначить, а rvalue — то, что вы можете назначить.
Тем не менее, это постепенно становится все дальше и дальше от истины. Простой пример lvalue, который вы не можете назначить, это const
переменная.
const int x = 5;
x = 6; // Error
Вы можете даже видеть rvalue в левой части назначения, когда вы включаете перегрузку оператора.
Я считаю более полезным думать о lvalue как о ссылке на объект, хранящийся в памяти, а rvalue как просто значение (которое, возможно, было прочитано из памяти). Концепции достаточно хорошо отражают эту идею. Некоторые примеры:
&
) требует lvalue, потому что вы можете взять только адрес чего-либо в памяти. Ему не нужно получать значение объекта, чтобы определить его адрес.std::move
превращение выражения lvalue в выражение rvalue можно представить как обман, заставляющий компилятор думать, что объект, хранящийся в памяти, на самом деле является лишь временным значением.Тем не менее, это также не действует в каждой ситуации. Это просто разумная аналогия.
В былые времена «lvalue» означало что-то, что могло бы оставил сторона назначения, а «значение» означало что-то, что может пойти на право сторона задания.
Это довольно интуитивно понятно, если подумать, с какой стороны оператора присваивания они могут появиться:
left-value = right-value;
Слабо говоря, lvalue
означает, что вы можете назначить ему, rvalue
означает, что он может появиться только на правой стороне оператора.
В С, lvalue
а также rvalue
отразить использование в операторе присваивания. rvalue
может появиться только справа от =
, в то время как lvalue
может быть с любой стороны. В C ++ это похоже, но сложнее.
Есть не присваиваемые lvalues
постоянные переменные.
Это является результатом упрощения (несколько более сложной) концепции.
lvalue
с оставил значения, т.е. е. те, которые «могут быть на левой стороне задания». Это, опять же, упрощение, не все l-значения могут быть непосредственно назначены как есть (например, массивы не могут, только элементы неconst
массивы, поэтому требуется подписка).
rvalues
являются право значения, которые могут быть только в правой части выражения присваивания.