Я пытаюсь понять типы выражений C ++, и чем больше я читаю, тем больше я запутался, поскольку нахожу черновик C ++ очень сложным для восприятия и поэтому предпочитаю другие ресурсы, но они либо противоречат друг другу, либо не учитывают, что формулировка и определение между версиями C ++ сильно изменяются.
Далее я ссылаюсь на следующие проекты:
- C ++ 11 [ n3690 ] (окончательный вариант)
- C ++ 17 [ n4659 ] (окончательный вариант)
- C ++ 20 [ n4835 ] (текущий проект)
C++11
3.10 Lvalues и rvalues... prvalue («чистое» rvalue) - это rvalue, которое не является xvalue. [Пример: результат вызова функции, тип возвращаемой которой не является ссылкой, является предварительным значением. Значение литерала, такого как 12, 7.3e5 или true, также является prvalue. - конец примера]
C++17
3.10 Lvalues и rvalues... prvalue - это выражение, вычисление которого инициализирует объект или битовое поле или вычисляет значение операнда оператора, как определено контекстом, в котором оно появляется.
C++20
7.2.1 Значимые категории *... prvalue - это выражение, вычисление которого инициализирует объект или битовое поле или вычисляет значение операнда оператора, как определено контекстом, в котором он появляется, или выражение, имеющее тип cv void.
Я бы понял изменения формулировки, и некоторые изменения сделаны, но для меня все определение изменяется. Может ли кто-нибудь помочь мне понять это? Например, почему было удалено предложение о том, что prvalue - это rvalue, а не xvalue? Или почему был удален полезный пример?
Ответы:
Первоначальное определение prvalue представляло собой просто метку: мы откладываем определенные значения (а именно те, которые не являются значениями x) и присваиваем им имя. Невозможно получить их адрес, кроме как с помощью необычного
this
использования (более или менее потому, что они временные), поэтому определенные свободы можно использовать при их создании и распространении, не нарушая ничего. (См. Также недавнее обсуждение того, что у них нет «идентичности».)Новое определение явно говорит, что prvalue - это инициализация, «ожидающая выполнения»: как только целевой объект идентифицирован для него, это то, что инициализируется. (Важно отметить, что инициализация по-прежнему происходит при построении prvalue, но не там, где он есть.) Это называется «исключение обязательного копирования» на основе эквивалентной оптимизации, которая уже была распространена.
Что касается примера, то новые определения категорий значений выглядели настолько простыми, что требовалось меньше примеров. Есть еще один для xvalues (которые являются самой тонкой категорией).
источник