Почему типы выражений менялись в C ++ между версиями?

13

Я пытаюсь понять типы выражений 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? Или почему был удален полезный пример?

Дэниел Стивенс
источник
3
Я за то, чтобы запретить языковые теги для конкретных версий За исключением именно таких вопросов.
любопытный парень
« Не принимайте во внимание, что формулировка и определение между версиями C ++ сильно изменяются». Но определение не изменилось. Значительное количество выражений, которые были prvalue в C ++ 11, все еще являются prvalue в C ++ 20.
Николь Болас
Где «противоречие (ион)» между версиями? Какой у вас вопрос?
Галигатор
1
Извините за изменение C ++ 20 , но я заметил несоответствие в стандарте.
Maggyero

Ответы:

5

Первоначальное определение prvalue представляло собой просто метку: мы откладываем определенные значения (а именно те, которые не являются значениями x) и присваиваем им имя. Невозможно получить их адрес, кроме как с помощью необычного thisиспользования (более или менее потому, что они временные), поэтому определенные свободы можно использовать при их создании и распространении, не нарушая ничего. (См. Также недавнее обсуждение того, что у них нет «идентичности».)

Новое определение явно говорит, что prvalue - это инициализация, «ожидающая выполнения»: как только целевой объект идентифицирован для него, это то, что инициализируется. (Важно отметить, что инициализация по-прежнему происходит при построении prvalue, но не там, где он есть.) Это называется «исключение обязательного копирования» на основе эквивалентной оптимизации, которая уже была распространена.

Что касается примера, то новые определения категорий значений выглядели настолько простыми, что требовалось меньше примеров. Есть еще один для xvalues ​​(которые являются самой тонкой категорией).

Дэвис Херринг
источник
Спасибо вам и комментаторам! Это в значительной степени объясняет это!
Даниэль Стивенс