Considerar:
void foo() {
std::vector<std::atomic<int>> foo(10);
...
}
¿Son válidos los contenidos de foo ahora? ¿O necesito recorrerlos e inicializarlos explícitamente? He comprobado Godbolt y parece estar bien, sin embargo, el estándar parece estar muy confundido en este punto.
El constructor std :: vector dice que inserta instancias insertadas por defecto de std::atomic<int>
, que son valores inicializados a través de la colocación new
.
Creo que se aplica este efecto de inicialización de valor:
2) si T es un tipo de clase con un constructor predeterminado que no es ni proporcionado por el usuario ni eliminado (es decir, puede ser una clase con un constructor predeterminado implícitamente definido o predeterminado), el objeto está inicializado en cero y luego es default-initialized si tiene un constructor predeterminado no trivial;
Entonces me parece que los atómicos están inicializados en cero. Entonces la pregunta es, ¿la inicialización cero de un std::atomic<int>
resultado en un objeto válido?
¿Voy a adivinar que la respuesta es "sí en la práctica pero no está realmente definida"?
Nota: Esta respuesta concuerda en que está inicializada en cero, pero en realidad no dice si eso significa que el objeto es válido.
atomic_init
. De todos modosIncluso si se llamara al constructor predeterminado (no lo es, porque es trivial), en realidad no hace nada .
Obviamente, no se puede garantizar que la inicialización cero produzca un valor atómico válido; esto solo funcionará si por casualidad se crea un atómico válido inicializando a cero todos sus miembros.
Y, dado que los atómicos no son copiables, no puede proporcionar un valor de inicialización en el constructor de vectores.
Ahora debe recorrer el contenedor y
std::atomic_init
cada elemento. Si necesita bloquear esto, está bien porque ya está sincronizando la creación del vector por la misma razón.fuente