Почему Visual C++ 2015 позволяет присваивать std::atomic?
Несколько дней назад я написал что-то вроде следующего:
struct A {
std::atomic_bool b = false;
};
Скомпилировано в Visual Studio 2015 Update 3 с компилятором VC++2015, ничего плохого не появилось.
Теперь я перекомпилировал то же самое с GCC (5.4.0) в Ubuntu и получил ошибку:
использование удаленной функции 'std::atomic::atomic(const std::atomic&)
Я получил ту же ошибку на ideone, установлен на C++14 (не уверен, какую версию компилятора он использует).
Конечно, изменение кода на следующее решило проблему с gcc:
struct A {
std::atomic_bool b { false };
};
Мои вопросы:
1. кто здесь прав (совместим с C++11), VC++ или GCC? Кажется, что VC++ вызывает конструктор из bool, в то время как GCC вызывает конструктор копирования (удалено).
2. Для целей инициализации значения по умолчанию атома в объявлении класса является ли равномерная инициализация (см. Выше) правильным / предпочтительным способом? Или я должен вместо этого использовать макрос ATOMIC_VAR_INIT (тьфу!)?
struct A {
std::atomic_bool b = ATOMIC_VAR_INIT(false);
};
1 ответ
ВК здесь не так. Pre-C++17 семантически код X x = y
означает вызов X tmp(y)
с последующим вызовом X(tmp)
есть конструктор копирования, семантически вызванный.
В то время как все известные мне компиляторы исключают промежуточный вызов (стандарт позволяет это делать), программа все еще плохо сформирована. Похоже, что VC неправильно применяет семантику.
В C++ 17 семантика этого вызова изменилась бы, и для этого потребовался бы только один вызов конструктора инициализации, таким образом, код станет правильно сформированным.