Можно ли вот так почистить фразу из рабочего проекта C++ n4928 (относительно обязательного копирования при инициализацииC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Можно ли вот так почистить фразу из рабочего проекта C++ n4928 (относительно обязательного копирования при инициализации

Сообщение Anonymous »

Итак, есть фраза из рабочего проекта стандарта C++ (n4928):
[dcl.init.general] ¶ 16.6.1

Если выражение инициализатора является значением prvalue, а неквалифицированная cv версия исходного типа совпадает с целевой type, выражение инициализатора используется для инициализации целевого объекта [Пример 2: T x = T(T(T())); значение инициализирует x. — end example]

Для меня слова «используется для инициализации» звучат как бесконечная рекурсия... А если нет, то почему читатель Стандарта должен думать, что ни конструкторы копирования, ни перемещения T не вызываются? Похоже, авторы подразумевали это значение:

Если выражение инициализатора является значением prvalue, а неполная cv версия исходного типа совпадает с типом назначения, для инициализируемого объекта не вызываются конструкторы, и его начальное значение является значением выражения инициализатора. [Пример 2: T x = T(T(T())); ни конструкторы копирования, ни перемещения не вызываются, но значение объекта x такое же, как и для T(), значение которого, в свою очередь, создается в соответствии с [expr.type.conv]. — end example]

Таким образом, в новой версии ¶ 16.6.1 явно больше нет рекурсии, а в этом примере T() с очевидными двумя вызовами конструктора копирования или перемещения (которые рассматриваются в следующем абзаце [dcl.init.general] ¶ 16.6.2 относительно прямая инициализация из исходного типа того же класса) вместо этого будет обрабатываться пунктом 16.6.1. Таким образом, на самом деле не будет ни вызовов конструкторов копирования, ни перемещения (как и предполагалось).
Новая формулировка также будет такой же, как и старая фраза в [dcl.init.general] ¶ 16.9, и будет соответствовать еще более старому определению термина value в стандарте C99...

значение — точное значение содержимого объекта при интерпретации как имеющего определенный тип

В C++98 авторы написали два предложения и фактически указали, что означает инициализация выражением: оценка его значения. Я предлагаю очистить ¶ 16.6.1 аналогичной формулировкой (см. выше).

Инициализатор скаляра должен представлять собой одно выражение, возможно, заключенное в фигурные скобки. Начальное значение объекта равно значению выражения (после преобразования);

...Хорошо, я нашел недостающую часть в [expr.type.conv] ¶ 1.4, и если вам не нравится моя формулировка, предложенная выше, то вам может понравиться вот эта:
[dcl.init.general] ¶ 16.6.1 (исправлено)

Если выражение инициализатора является значением prvalue, а неполная cv версия исходного типа совпадает с типом назначения, инициализируемый объект является объектом результата выражения инициализатора. [Пример 2: T x = T(T(T())); x инициализируется напрямую конструктором T по умолчанию в соответствии с [expr.type.conv]. — конец примера]

[dcl.init.general] ¶ 16.9 (исправлено)

В противном случае инициализируемый объект является объектом результата (возможно, преобразованного) выражения инициализатора.

Как насчет этого варианта?
Эта часть стандарта важна, поскольку она делает обязательной так называемую оптимизацию неименованного возвращаемого значения (URVO) для компиляторов, начиная с C++17...

Подробнее здесь: https://stackoverflow.com/questions/797 ... atory-copy
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»