Подтвердить что ты не робот

Ошибка "Использовать удаленную функцию" с помощью 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;
                        ^

Любая идея о том, что происходит?

4b9b3361

Ответ 1

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

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

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

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

Если инициализатор представляет собой (не заключенный в скобки) бит-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

Ответ 2

В моем случае у меня были следующие ошибки (Примеры):

• 'std :: literals не был объявлен

using namespace std::literals::string_literals;

• Ошибка "Использование удаленной функции" с std :: random_device {}

std::random_device device = std::random_device{}  

Проверьте, какой выбранный вами стандарт C++. В моем случае в режиме отладки я выбрал -std = C++ 17, ВСЕ ОК. Но в режиме Release я выбрал -std: C++ 11, тонны ошибок.

Обновление Протестировано на Clion Windows 2018.3 с удаленной компиляцией Linux.

Используя -std = C++ 11 Using -std=c++11

Используя -std = C++ 17 Using -std=c++17

С++ является развивающимся стандартом: после 2003 года были 2011 (С++ 11), затем 2014 (С++ 14), и теперь у нас есть 2017 (С++ 17), и мы работаем на 2020 год (С++ 20 ) Многие вещи меняются, они устарели, другие функции являются новыми. Если вы хотите последнее обновление, вам следует использовать самый последний стандарт, если в вашем программном обеспечении есть код, который может быть устаревшим, тогда вам следует использовать стандарт, с которым оно было создано.