Итак, есть фраза из рабочего проекта стандарта 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
Можно ли вот так почистить фразу из рабочего проекта C++ n4928 (относительно обязательного копирования при инициализации ⇐ C++
Программы на C++. Форум разработчиков
1760454587
Anonymous
Итак, есть фраза из рабочего проекта стандарта C++ (n4928):
[b][dcl.init.general][/b] [b]¶ 16.6.1[/b]
Если выражение инициализатора является значением 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() с очевидными двумя вызовами конструктора копирования или перемещения (которые рассматриваются в следующем абзаце [b][dcl.init.general][/b] [b]¶ 16.6.2[/b] относительно прямая инициализация из исходного типа того же класса) вместо этого будет обрабатываться пунктом 16.6.1. Таким образом, на самом деле не будет ни вызовов конструкторов копирования, ни перемещения (как и предполагалось).
Новая формулировка также будет такой же, как и старая фраза в [b][dcl.init.general][/b] [b]¶ 16.9[/b], и будет соответствовать еще более старому определению термина value в стандарте C99...
значение — точное значение содержимого объекта при интерпретации как имеющего определенный тип
В C++98 авторы написали два предложения и фактически указали, что означает инициализация выражением: оценка его значения. Я предлагаю очистить ¶ 16.6.1 аналогичной формулировкой (см. выше).
Инициализатор скаляра должен представлять собой одно выражение, возможно, заключенное в фигурные скобки. Начальное значение объекта равно значению выражения (после преобразования);
...Хорошо, я нашел недостающую часть в [b][expr.type.conv][/b] [b]¶ 1.4[/b], и если вам не нравится моя формулировка, предложенная выше, то вам может понравиться вот эта:
[b][dcl.init.general][/b] [b]¶ 16.6.1[/b] (исправлено)
Если выражение инициализатора является значением prvalue, а неполная cv версия исходного типа совпадает с типом назначения, инициализируемый объект является объектом результата выражения инициализатора. [Пример 2: T x = T(T(T())); x инициализируется напрямую конструктором T по умолчанию в соответствии с [expr.type.conv]. — конец примера]
[b][dcl.init.general][/b] [b]¶ 16.9[/b] (исправлено)
В противном случае инициализируемый объект является объектом результата (возможно, преобразованного) выражения инициализатора.
Как насчет этого варианта?
Эта часть стандарта важна, поскольку она делает обязательной так называемую оптимизацию неименованного возвращаемого значения (URVO) для компиляторов, начиная с C++17...
Подробнее здесь: [url]https://stackoverflow.com/questions/79789204/can-i-clean-the-phrase-of-the-c-n4928-working-draft-regarding-mandatory-copy[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия