Этот вопрос это здорово, потому что у него есть ответы на какие различия между rvalue
, lvalue
, xvalue
, glvalue
, а также prvalue
, Верхний ответ имеет достойное объяснение каждого, и я понимаю их различия, когда я читаю их. Однако мне трудно держать их прямо в голове, и мне приходится гуглить их каждый раз, когда кто-то использует эти термины, чтобы напомнить себе, какой из них какой.
Существуют ли общие мнемоники или другие способы, которыми люди помнят, какой из них какой? Я действительно хотел бы иметь возможность держать их прямо в голове, не путая их, как я делаю в настоящее время.
Я делаю 2 ассоциации:
std::move
выражениеЕсли это не так, то это, вероятно, prvalue.
Теперь, чтобы запомнить glvalues и rvalues, я просто представляю этот график:
lvalues и xvalues оба являются glvalues, в то время как xvalues и prvalues оба являются rvalue. Это действительно все, что вам нужно знать на практике.
Может быть, мнемоника для запоминания lvaluse, xvalues и prvalues идут внизу — это слова Lower eXPRessions
(содержит L, X и PR). Возможно, нет.
Обычно вам нужно знать, является ли что-то lvalue или rvalue. Эти две категории выражений отличаются друг от друга.
Это обычно тот случай, когда выражение lvalue относится к чему-то, что будет какое-то время зависать. Например, имя переменной является lvalue, потому что переменные остаются. С другой стороны, выражения rvalue обычно ссылаются на то, что существует только временно. Вы можете взять только адрес lvalue, потому что с какой стати вам нужен адрес чего-то, что скоро исчезнет?
Теперь, делая это различие, вы должны принять во внимание, что Компилятор знает в это время. Например, возьмите функцию void foo(const A& a)
, Внутри этой функции компилятор не знает, был ли переданный объект временным объектом или нет, поэтому он просто предполагает, что он останется. То есть, a
это значение. Даже если вы можете с радостью передать временный объект в эту функцию (вызвать его с помощью выражения rvalue), выражение a
все еще lvalue.
Принимая это во внимание, вы можете дополнительно вспомнить, является ли что-то lvalue или rvalue по тому, как оно названо. В приведенном выше примере, поскольку объект получает имя как a
Это lvalue.
Теперь для остальных категорий вы должны запомнить следующую диаграмму:
Обратите внимание, что значения и значения действительно различны. Тем не менее, rvalues делятся на две другие категории, xvalues и prvalues. Кроме того, xvalues также считается glvalues вместе со всеми выражениями lvalue.
Теперь, зная, когда они появятся, нужно вспомнить несколько случаев.
xvalues не очень распространены Они появляются только в ситуациях, связанных с преобразованием в ссылки на значения. Вот все случаи:
object.x
если object
это значениеobject.*member
если pobject
это значениеПо определению, prvalues любой другой тип rvalue, который не является xvalue. Например, возвращение объекта по значению из функции создает временный возвращаемый объект. Выражение, обозначающее этот объект, является prvalue.
Категория glvalue используется для обозначения всего, что не является ценным.
Lvalue можно рассматривать как «именованную» переменную или область памяти… rvalue можно рассматривать как «unamed» область памяти (т. Е. Временную переменную, возвращаемую из функции) или чистое «значение» (т.е. как номер).