Почему 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 семантика этого вызова изменилась бы, и для этого потребовался бы только один вызов конструктора инициализации, таким образом, код станет правильно сформированным.

Другие вопросы по тегам