Q: почему _rvalues_ были переименованы в _prvalues_? (чистые значения)

Этот документ является источником этих изменений в C ++ 11: n3055.

II. Обзор изменений

Rvalues, как в настоящее время известно в основных предложениях языка, переименовывается
чтобы «prvalues»(« Чистые »значения).

lvalues смысл не изменился, но glvalues были представлены для покрытия xvalues.

Почему бы не сделать то же самое для rvalues?!

rvalues смысл должен был остаться без изменений, но ввести grvalues покрывать xvalues тоже.
(prvalues можно заменить обратно на простой rvalues в симметрии с тем, как lvalues определены)

      expression
/        \
glvalue    grvalue
/     \    /     \
lvalue   xvalue   rvalue

Ценовые категории можно определить более просто:

  • именующий имеет идентичность но не может быть перемещен из; это glvalue, который не является xvalue
  • Rvalue не имеет идентичности, но может быть переехала из; это grvalue, который не является xvalue
  • xvalue имеет идентичность и может быть переехала из.

Каждое выражение является либо именующий, xvalue или же Rvalue.

0

Решение

Понятие rvalues ​​было сделано более общим, и сущность rvalues ​​была определена как отсутствие псевдонимов. Была добавлена ​​новая категория значений, xvalues, которая разделяет это свойство, а подмножество rvalues, которое присутствовало до C ++ 11, было переименовано в prvalues ​​(«чистые rvalues»).

Два основных раздела, которые мы хотим получить, теперь таковы:

  • glvalue против prvalue: glvalue — это объекты (= места хранения); prvalues ​​являются традиционными «временными» (но см. ниже).
  • lvalue vs rvalue: lvalue связывается со ссылками lvalue, rvalue связывается со ссылками rvalue. Это различие необходимо для определения работы ссылок и привязки ссылок.

Xvalue — это и glvalue, и rvalue. Это отражает тот факт, что ссылки на rvalue — это способ выполнить преобразование lvalue в xvalue (через приведение, std::move), то есть иметь определяемые пользователем значения. Они также позволяют преобразование в другом направлении, из prvalue в lvalue, путем привязки rvalue к ссылке rvalue (которая теперь является lvalue).

C ++ 17 уточняет идею немного дальше, превращая prvalues ​​в «условные значения» или «нематериализированные значения», которые больше не являются объектами. На этой новой картине только объекты являются объектами. Однако значения могут быть материализованные в объекты, которые соответственно называются «преобразованием prvalue-to-glvalue».

Этот новый способ мышления о категориях значений означает, что если у вас есть функция T f();, где T не ссылка, то выражение f() сам по себе не является объектом (следовательно, не требует копирования объектов!), но когда это необходимо (например, если вы говорите f().x), объект создается и инициализируется значением prvalue (= materialized), чтобы разрешить доступ к элементу.


Может быть, стоит обобщить все преобразования, которые существуют в C ++ 17:

  • «glvalue-to-prvalue»: это то, что C называет «преобразованием lvalue». Пример: int a = 1; 1 + a; Второй операнд выражения сложения является prvalue, полученным преобразованием glvalue-prvalue в a,

  • «rvalue-to-lvalue»: Предоставляется ссылками rvalue. Пример: int && r = e, Вот e является выражением Rvalue, и r является lvalue, обозначающим тот же (или потенциально материализованный) объект.

  • «prvalue-to-glvalue»: это материализация prvalue, где ожидается glvalue.

  • «lvalue-to-rvalue»: доступно только как «lvalue-to-xvalue» через std::moveнапример, int a; static_cast<int&&>(a);,

Обратите внимание, что все пары, которые появляются в списке, имеют одинаковое количество букв — либо обе имеют одну букву, либо обе имеют две. Я думаю, что это является следствием правильно выбранной таксономии, которой нет в предложенной вами альтернативе.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]