std :: вектор класса, содержащего атомарный - PullRequest
0 голосов
/ 14 мая 2018

Я пытаюсь создать вектор, содержащий экземпляры класса, который, в свою очередь, содержит (среди прочего) std :: atomic.

Я пробовал несколько:

  • если конструктор копирования не указан, компилятор выдаст ошибку об удаляемом конструкторе.

Если указан конструктор копирования, я попробовал две вещи:

  • при использовании foo (foo & other) он будет жаловаться, что не найден конструктор копирования для foo.

    Редактировать: конструктором копирования является foo (foo & other): atomic (other.atomic).load ()) {}

  • с foo (const foo & other) будет жаловаться на отсутствие конструктора const-копии для std :: atomic.

    Редактировать:конструктор копирования foo (const foo и другие): atomic (other.atomic.load ()) {}

Я абсолютно не имею понятия, как это исправить, поэтому любая помощь оченьцениться

1 Ответ

0 голосов
/ 14 мая 2018

std::atomic не является ни копируемым, ни подвижным, в соответствии с дизайном.Операции на std::vector, которые вызывают его перераспределение, требуют, чтобы его элементы были как минимум подвижными.Итак, у вас есть следующие опции:

  • Прекратить сохранение std::atomic в классе элемента.Возможно, вместо этого можно было бы использовать std::unique_ptr<std::atomic>.
  • Прекратите хранить класс элемента непосредственно в векторе, вместо этого сохраните std::unique_ptr<ElementClass> (как предложено @Richard Critten в комментариях).
  • Написатьконструктор копирования или перемещения и оператор присваивания для вашего класса, который каким-то образом обойдёт неподвижность std::atomic.
  • Дайте вашим классам фиктивные операции копирования / перемещения, чтобы удовлетворить компилятор.Затем предварительно выделите пространство в векторе, используя reserve, а затем используйте только функции, которые добавляют элементы (до предварительно выделенного размера), получают к ним доступ или удаляют с конца;никаких вставок или удалений посередине.Таким образом, фиктивные операции никогда не будут вызываться.

    Учитывая хрупкость этого подхода, я бы предложил две меры предосторожности:

    1. Сделайте броски манекенов, чтобы вы могли поймать любогонарушения требования «без изменения размера» как можно скорее.
    2. Не используйте std::vector напрямую, но оберните его в свой собственный NonResizableVector<T> с соответствующим ограниченным интерфейсом и документально его документируйте.

Какой из них вы должны (или даже можете) использовать, зависит от того, что на самом деле делает ваш класс.

...