12.6.1 - Явная инициализация
struct complex {
complex();
complex(double);
complex(double,double);
};
complex sqrt(complex,complex);
complex g = { 1, 2 }; // construct complex(1, 2)
// using complex(double, double)
// and *copy/move* it into g
8.5 Инициализаторы
14 - Инициализация, которая происходит в форме
T x = a;
а также при передаче аргументов, возврату функции, выделении исключения (15.1), обрабатывая исключение (15.3) и совокупный член инициализация (8.5.1) называется копированием-инициализацией. [Заметка: Копирование-инициализация может вызвать ход (12.8). - конечная нота]
15 - Инициализация, которая происходит в формах
T x(a);
T x{a};
а также в новых выражениях (5.3.4), выражения static_cast (5.2.9), преобразования типов функциональных обозначений (5.2.3), а также базы и член инициализаторы (12.6.2) называется прямой инициализацией.
8.5.4 List-initialization [dcl.init.list]
1 - Инициализация списка - это инициализация объекта или ссылки из бит-init-список. Такой инициализатор называется списком инициализаторов, и разделяемые запятыми инициализаторы-предложения списка называются элементы списка инициализаторов. Список инициализаторов может быть пустым. Инициализация списка может возникать при прямой инициализации или инициализации копирования контексты; инициализация списка в контекст прямой инициализации называется инициализацией прямого списка и инициализация списка в контексте копирования-инициализациикопирование списка инициализация.
Проблема с атоматикой
29.6.5 Требования к операциям с атомными типами [atomics.types.operations.req]
#define ATOMIC_VAR_INIT(value)
см. нижеМакрос расширяется до последовательности токенов, подходящей для константы инициализация атомной переменной статической продолжительности хранения тип, который инициализирован-совместим со значением. [Примечание: это может потребоваться инициализация блокировок. - конечная нота] Параллельный доступ к инициализированной переменной, даже посредством атомной операции, представляет собой гонку данных. [Пример:
atomic<int> v = ATOMIC_VAR_INIT(5);
В соответствии с предыдущими разделами, похоже, не должно быть инициализации присваивания без задействованного конструктора-копии, даже если он отклоняется в соответствии с §12.8.31 и §12.8.32, но атомизация определяется как:
29.5 Атомные типы [atomics.types.generic]
atomic() noexcept = default;
constexpr atomic(T) noexcept;
atomic(const atomic&) = delete;
atomic& operator=(const atomic&) = delete;
atomic& operator=(const atomic&) volatile = delete;
T operator=(T) volatile noexcept;
T operator=(T) noexcept;
Нет конструктора-копии!
Часто ATOMIC_VAR_INIT
расширяется до выражения скобки для инициализации скобки, но atomic<int> v = {5}
по-прежнему является инициализацией присваивания и подразумевает построение копии после прямого построения временного.
Я просмотрел раздел "постоянная инициализация", чтобы увидеть, есть ли лазейка, разрешающая это без копии (из-за "Макрос расширяется до последовательности токенов, подходящей для постоянной инициализации атомной переменной статической продолжительности хранения тип, который инициализирован-совместим со значением" ), но я уже отказываюсь.
Связанные дискуссиях:
http://thread.gmane.org/gmane.comp.lib.qt.devel/8298
http://llvm.org/bugs/show_bug.cgi?id=14486
ИЗМЕНИТЬ
Ответ на цитирование соответствующих стандартных разделов при построении процесса дедукции был бы идеальным.
Заключение
Итак, после приятного ответа Николаса Боласа, забавный вывод состоит в том, что complex g = { 1, 2 }
- это копия (это контекст инициализации копирования), которые не копируются (инициализация списка копий разрешается как инициализация с прямым списком), для которых в стандарте предлагается операция копирования (12.6.1: ...and copy/move it into g
).
FIX
Запрос Pull: https://github.com/cplusplus/draft/pull/37