Там есть пункт о гарантированной копии элизии в C++ проект n4606 [dcl.init] 17.6:Как гарантированное копирование elision работает в инициализации списка в C++ 1z?
- Если тип назначения (возможно, резюме квалифицированных) Тип класса:
- Если выражение инициализатора является prvalue, а cv-unqualified версия типа источника - это тот же класс, что и класс адресата, выражение инициализатора используется для инициализации целевого объекта. [Пример:
T x = T(T(T()));
вызывает конструктор по умолчаниюT
для инициализацииx
. - конец пример]- [...]
Существует также Q&A говорит о том, как это работает.
Для меня я понял, что правило, которое я цитировал, гарантирует, что никакие ctors не должны взаимодействовать, когда выражение инициализатора является prvalue, а cv-неквалифицированная версия типа источника - это тот же класс, что и класс назначения. Так что нет нужды, чтобы проверить наличие копии или перемещения CTOR, что делает следующие коды, чтобы быть законным в C++ 17:
struct A {
A() {}
A(A const &) = delete;
A(A &&) = delete;
};
A f() { return A(); } // it's illegal in C++14, and suppose to be legal in C++17
Однако то, что сводит меня с ума, я не могу найти аналогичные правила в списке раздел инициализации в проекте C++ n4606. То, что я нашел ([dcl.init.list] 3,6)
[...]
- В противном случае, если
T
является тип класса, конструкторы рассматриваются. Применяемые конструкторы перечисляются, а лучший выбирается с помощью разрешения перегрузки (13.3, 13.3.1.7). Если для преобразования любого из аргументов требуется сужение преобразования (см. Ниже), программа плохо сформирована. [...]
Поскольку список инициализация имеет более высокий приоритет, чем первое правило я цитировал, мы должны учитывать правило в списке инициализируются секции при инициализации является инициализатор-лист. Как мы видим, конструкторы учитываются при инициализации списка типа класса T
. Таким образом, продолжение предыдущего примера будет
A ff() { return {A()}; }
юридический в C++ 17? И может ли кто-нибудь найти, где в стандартном проекте указывается, как работает гарантированное копирование при инициализации списка?
Гарантированное копирование будет работать со сценарием инициализации списка только для агрегатов из-за специального правила для агрегатов, инициализированных с объектом того же типа в C++ 17 .. Но остальные случаи, похоже, не гарантируются гарантированным копировать. Но помните, что вы можете просто отбросить фигурные скобки, и это сработает. Я не вижу причин поместить фигурные скобки. –
Обратите внимание, что даже не гарантированное копирование будет работать здесь (afaics .. это не инициализация, а конкретное приложение разрешения перегрузки и вызов конструктора .. поэтому он не должен быть покрыт правилами элиции, если явно), поэтому это не проблема, введенная C++ 17. –
Я поставил вопрос на обсуждение std: https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/3EvAt9v4dYE –