Инициализировать переменную статического атома

Я хотел бы генерировать идентификаторы для класса с именем order в потоковом режиме. Код ниже не компилируется. Я знаю, что у атомных типов нет конструкторов копирования, и я предполагаю, что это объясняет, почему этот код не работает. Кто-нибудь знает способ заставить этот код работать? Я все еще учусь, поэтому, пожалуйста, дайте мне знать, если я ошибаюсь (если так, я был бы признателен, если бы вы могли указать мне на альтернативный подход). Спасибо!

#include <atomic>
#include <iostream>

class order {
public: 
    order() { id=c.fetch_add(1); }
    int id;
private:
    static std::atomic<int> c;
};

std::atomic<int> order::c = std::atomic<int>(0);

int main() {
    order *o1 = new order();
    order *o2 = new order();
    std::cout << o1->id << std::endl; // Expect 0
    std::cout << o2->id << std::endl; // Expect 1
}

Сопоставление приведенных выше результатов со следующей ошибкой:

order.cpp:45:51: error: use of deleted function 
        ‘std::atomic<int>::atomic(const std::atomic<int>&)’
In file included from order.cpp:3:0:
/usr/include/c++/4.7/atomic:594:7: error: declared here

Ответ 1

Я знаю, что у атомных типов нет конструкторов копирования, и я предполагаю, что это объясняет, почему этот код не работает.

Да, ошибка говорит об этом довольно четко.

Кто-нибудь знает способ заставить этот код работать?

Вместо инициализации копирования из временного, для которого требуется доступный конструктор копирования:

std::atomic<int> order::c = std::atomic<int>(0);

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

std::atomic<int> order::c(0);   // or {0} for a more C++11 experience

Вы, вероятно, предпочтете это, если вам не нравится читать ненужный подробный код.

Ответ 2

Как насчет определения

std::atomic<int> order::c{0}

Ответ 3

Также вы можете использовать atomic_init:

std::atomic<int> data;
std::atomic_init(&data, 0);