Considérer:
void foo() {
std::vector<std::atomic<int>> foo(10);
...
}
Le contenu de foo est-il maintenant valide? Ou dois-je les parcourir explicitement et les initialiser? J'ai vérifié Godbolt et ça semble bien, mais la norme semble être très confuse sur ce point.
Le constructeur std :: vector dit qu'il insère des instances insérées par défaut de std::atomic<int>
, dont la valeur est initialisée via placement new
.
Je pense que cet effet d'initialisation de la valeur s'applique:
2) si T est un type de classe avec un constructeur par défaut qui n'est ni fourni par l'utilisateur ni supprimé (c'est-à-dire qu'il peut s'agir d'une classe avec un constructeur par défaut implicitement défini ou par défaut), l'objet est initialisé à zéro puis il est initialisé par défaut s'il a un constructeur par défaut non trivial;
Il me semble donc que les atomes sont initialisés à zéro. La question est donc de savoir si l'initialisation à zéro d'un std::atomic<int>
résultat aboutit à un objet valide?
Je vais deviner que la réponse est "oui dans la pratique mais ce n'est pas vraiment défini"?
Remarque: Cette réponse convient qu'il est initialisé à zéro, mais ne dit pas vraiment si cela signifie que l'objet est valide.
atomic_init
. Vous devez déjà synchroniser autour du code de la question de toute façonMême si le constructeur par défaut était appelé (ce n'est pas le cas, car c'est trivial), il ne fait vraiment rien .
Une initialisation nulle ne peut évidemment pas être garantie pour produire un atomique valide; cela ne fonctionnera que si par hasard un atomique valide est créé en initialisant zéro tous ses membres.
Et, comme l'atomique n'est pas copiable, vous ne pouvez pas fournir de valeur d'initialisation dans le constructeur vectoriel.
Vous devez maintenant faire une boucle sur le conteneur et
std::atomic_init
chaque élément. Si vous avez besoin de contourner cela, c'est bien parce que vous synchronisez déjà la création du vecteur pour la même raison.la source