Чому std :: атомний конструктор поводиться по-різному в C ++ 14 і C ++ 17


19

Я працюю над проектом на C ++ 11 і спробував наступний код

#include <atomic>

struct A {
    std::atomic_int idx = 1;

};

int main() {
    return 0;
}

Я отримую помилку компілятора

error: use of deleted function 'std::__atomic_base<_IntTp>::__atomic_base(const std::__atomic_base<_IntTp>&) [with _ITp = int]'
 std::atomic_int idx = 1;
                       ^

Той самий результат є з C ++ 14. Коли я переключаюсь на C ++ 17, це працює: wandbox

Я перевірив cppreference на відмінності:

Але різниці між C ++ 14 і C ++ 17 не зафіксовано. Чому це працює з C ++ 17, а не з C ++ 14?


Який компілятор / стандартну бібліотеку / платформу ви використовуєте?
Віктор Губін

@VictorGubin Я спробував із Clang та GCC на Linux (Wandbox). Я пробував різні версії.
Томас Саблік

1
Ви можете спростити MCVE до локального в main(або будь-якій функції, не потрібно main), а не конструктор структури. Кланг видає подібне повідомлення про помилку, будучи більш явним, що він намагається використовувати видалений конструктор копій замість ініціалізатора чи звичайного конструктора: godbolt.org/z/SBGf9w з libc ++
Пітер Кордес

@PeterCordes Я не був впевнений, чи пов’язана ця помилка з ініціалізацією класу.
Томас Саблік

3
Отримання того ж повідомлення про помилку для більш простого мінімально відтворюваного прикладу доводить, що це не так. Я також не був впевнений, поки не спробував.
Пітер Кордес

Відповіді:


29

Тому що в C ++ 17 є гарантоване RVO. У C ++ 14 тверджень, як Foo x = Foo(args)і Foo x (args)технічно, не однакові, але вони є в C ++ 17.

struct Foo {
    Foo() = default;
    Foo(const Foo&) = delete;
};

int main() {
    // Works in C++17 and C++20, fails in C++14 and before
    Foo foo = Foo(); 
}

Детальніше про це можна прочитати тут: https://en.cppreference.com/w/cpp/language/copy_elision

Зокрема розділ (since C++17):

T x = T (T (f ())); // лише один виклик конструктору T за замовчуванням для ініціалізації x

Для роботи коду C ++ 14 ви можете використовувати

std::atomic_int idx { 1 };
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.