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

Ошибка с оператором копирования/присваивания для класса, который имеет переменную std:: atomic member

У меня есть класс, как показано ниже.

#include <atomic>

static const long  myValue = 0;

class Sequence
{

public:

    Sequence(long initial_value = myValue) : value_(initial_value) {}


private:

     std::atomic<long> value_;
};

int main()
{
         Sequence firstSequence;
         Sequence secondSequence = firstSequence;
         return 0;
}

Я получаю ошибку компиляции, подобную этой,

test.cpp:21:36: error: use of deleted function ‘Sequence::Sequence(const Sequence&)’
test.cpp:5:7: error: ‘Sequence::Sequence(const Sequence&)’ is implicitly deleted because the default definition would be ill-formed:
test.cpp:5:7: error: use of deleted function ‘std::atomic<long int>::atomic(const std::atomic<long int>&)’

Это то, что конструктор копирования по умолчанию и операнд присваивания не работают в этом случае?

PS: Я использую gcc версии 4.6.3

4b9b3361

Ответ 1

Вы не можете копировать атоматику со стандартным конструктором копирования, так как все загрузки и магазины должны выполняться явно. Вам нужно написать собственный конструктор копирования для Sequence, который выполняет некоторую инициализацию формы value_(rhs.value_.load()) (возможно, с более расслабленным порядком памяти).

Ответ 2

Atomic удалил copy-ctor. Поэтому copy/move-ctors в вашем классе удаляются.

n3337 12,8/11

Неявно объявленный конструктор copy/move является встроенным публичным членом своего класса. По умолчанию копия / move для класса X определяется как удаленный (8.4.3), если X имеет:

- нестатический элемент данных класса M (или его массив), который нельзя скопировать/переместить, потому что (13.3), применительно к соответствующему конструктору Ms, приводит к двусмысленности или функция, которая удалена или недоступна для конструктора по умолчанию,

Ответ 3

Поскольку нет функции std::atomic<long int>::atomic(const std::atomic<long int>&), компилятор не может создать конструктор копии по умолчанию для класса Sequence. Если вам нужен конструктор копирования для этого класса (и если вы хотите, чтобы Sequence secondSequence = firstSequence; работал), вам нужно написать его.

Это требование требуется по стандарту:

Ниже приведены атомный интеграл и типы адресов. Эти типы должны иметь стандартную компоновку. Они должны иметь тривиальный конструктор по умолчанию, конструктор конструктивных конструкторов constexpr, конструктор удаленной копии, оператор делегирования удаленной копии и тривиальный деструктор. Эти типы должны поддерживать агрегатный синтаксис инициализации.

Ответ 4

Я бы предположил, что выбор для удаления конструктора копирования в стандарте был по двум причинам:

  • требуется пара загрузки/хранения. Есть ли способ обеспечить, чтобы это было сделано, если вы не контролируете вызывающих пользователей std:: atomic?

  • Что вы делаете, если тип std:: atomic < > , который вы использовали, был тем, для которого is_lock_free() является false (т.е. в реализации для этого типа целочисленного размера требуется мьютекс)? Какую семантику копирования вы используете для инициализации мьютекса? Мьютекс, который неявно скопирован, нуждается в повторной инициализации, поскольку он может быть несчастлив скопирован в заблокированном состоянии. Я предполагаю, что std:: mutex также имеет конструктор удаленной копии из-за этого, и это также вызывает требование в std:: atomic.