Ошибка "использование удаленной функции" с std:: atomic int

Я хочу использовать std::atomic_int переменной. В моем коде у меня есть:

#include <atomic>

std::atomic_int stop = 0;

int main()
{
    // Do something
}

и это дает мне ошибку при компиляции:

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

есть идеи, что происходит?

1 ответов


ваш код пытается построить временную std::atomic_int на RHS, затем используйте std::atomic_int конструктор копирования (который является deleted) инициализировать stop, например:

std::atomic_int stop = std::atomic_int(0);

потому что копирования-инициализации, как вы здесь выполняете, не совсем эквивалентно другим видам инициализации.

[C++11: 8.5/16]: семантика инициализаторов выглядит следующим образом [..]

если инициализатор A (без скобок) braced-init-list, объект или ссылка список-инициализации (8.5.4).

(это позволяет вариант 3, в конце этого ответа)

[..]

если тип назначения (возможно, CV-квалифицированный) тип класса:

  • если инициализации прямой инициализации или если это копирования-инициализации где CV-неквалифицированная версия исходного типа является тем же классом, что и производный класс класса назначения, рассматриваются конструкторы. перечисляются применимые конструкторы (13.3.1.3), и лучший из них выбирается с помощью разрешения перегрузки (13.3). Выбранный таким образом конструктор вызывается для инициализации объекта с выражением инициализатора или списком выражений в качестве аргументов. Если конструктор не применяется, или перегрузка разрешение неоднозначно, инициализация плохо сформирована.

(это почти описывает ваш код, но не совсем; ключ здесь в том, что, возможно, вопреки интуиции,std::atomic_intконструкторы не рассматриваются вообще в вашем случае!)

  • в противном случае (т. е. на оставшиеся копирования-инициализации случаях), определенное пользователем преобразование последовательности, которая может конвертировать из исходного типа в целевой тип. или (когда используется функция преобразования) в производный класс перечисляются, как описано в 13.3.1.4, и лучший из них выбирается с помощью разрешения перегрузки (13.3). Если преобразование не может быть выполнено или неоднозначно, инициализация плохо сформирована. выбранная функция вызывается с выражением инициализатора в качестве аргумента; если функция является конструктором, вызов инициализирует временную версию типа назначения cv-unqualified. Временное-это prvalue. результат вызова (который является временным для случая конструктора) затем используется для прямой инициализации, согласно правилам выше, объект, который является местом назначения копирования-инициализации. в некоторых случаях реализация разрешена для устранения копирования, присущего этому прямой инициализации путем построения промежуточного результата непосредственно в инициализируемый объект; см. 12.2, 12.8.

(это ваш сценарий; поэтому, хотя копия может быть удалена, она все равно должна быть возможна)

  • [..]

вот исправление, в любом случае; используйте прямой инициализации или список-инициализация:

std::atomic_int stop(0);     // option 1
std::atomic_int stop{0};     // option 2
std::atomic_int stop = {0};  // option 3