Ответ 1
Хорошо, существуют три категории выражений 1:
- те, которые представляют объекты, которые имеют идентификатор и не могут быть перемещены из;
- те, которые представляют объекты, которые имеют идентификатор и могут быть перемещены из;
- те, которые представляют объекты, которые не имеют идентификатора и могут быть перемещены из;
Первые называются lvalues, а вторыми являются значения x, а третьи - prvalues. Если мы поместим lvalues и xvalues вместе, мы получим glvalues. Glvalues - это все выражения, представляющие объекты с идентификатором. Если мы поместим xvalues и prvalues вместе, мы имеем rvalues. Rvalues - это все выражения, представляющие объекты, которые можно перемещать.
Соответствующее выражение x
является glvalue: можно написать &x
, поэтому объект явно имеет тождество.
Можем ли мы перейти от этого выражения? Срок действия этого объекта истекает? Нет. Он истекает через некоторое время после текущего выражения. Это означает, что он не может быть перенесен. Это делает его lvalue.
Все эти имена могут быть немного запутанными, потому что lvalue и rvalue в С++ больше не означают, что они имели в виду в их истоках C. Значение С++ полностью не связано с левой или правой стороной назначения 2.
Лично я предпочитаю использовать терминологию этой статьи по Bjarne: iM-значения (вместо lvalues), im-values (вместо xvalues), Im -значения (вместо prvalues), i-значения (вместо glvalues) и m-значения (вместо rvalues). Это не терминология, которую стандарт использует, к сожалению.
1 Здесь "имеет тождество" означает "его адрес может быть принят"; "может быть перемещен из" означает, что он скоро истечет либо из-за его временного характера, либо потому, что программист сделал это явным в системе типов, вызвав std::move
или что-то подобное.
2 Вы можете иметь rvalues в левой части назначения: std::vector<int>(17) = std::vector<int>(42)
является допустимым выражением, даже если оно бесполезно.