web-dev-qa-db-fra.com

Initialiser la variable membre atomique statique

Je voudrais générer des identificateurs pour une classe nommée order d'une manière threadsafe. Le code ci-dessous ne se compile pas. Je sais que les types atomiques n'ont pas de constructeurs de copie, et je suppose que cela explique pourquoi ce code ne fonctionne pas. Quelqu'un connaît-il un moyen de faire fonctionner ce code? J'apprends encore, alors s'il vous plaît, faites-moi savoir si je suis sur la mauvaise voie (si oui, j'apprécierais que vous me dirigiez vers une approche alternative). Merci!

#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
}

La compilation des résultats ci-dessus entraîne l'erreur suivante:

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
23
Teisman

Je sais que les types atomiques n'ont pas de constructeurs de copie, et je suppose que cela explique pourquoi ce code ne fonctionne pas.

Oui, l'erreur le dit très clairement.

Quelqu'un connaît-il un moyen de faire fonctionner ce code?

Au lieu de copier-initialiser à partir d'un temporaire, ce qui nécessite un constructeur de copie accessible:

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

utiliser l'initialisation directe, qui ne:

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

Vous devriez probablement préférer cela de toute façon, sauf si vous aimez lire du code inutilement verbeux.

44
Mike Seymour

Que diriez-vous de la définition

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

Vous pouvez également utiliser atomic_init:

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