2014-06-19 20 views
8

Diciamo che ho una classe con una serie membro del std::atomic s, in cui la matrice è dimensionato tramite un calcolo (vale a dire che possono cambiare in base su altre costanti altrove nel programma):Come inizializzare elegantemente una matrice di std :: atomic?

class Foo { 
    static constexpr size_t kArraySize = ComputeArraySize(); 
    std::atomic<size_t> atomics_[kArraySize]; 
}; 

Qual è la il modo più elegante per garantire che gli atomici siano tutti inizializzati su zero? Posso fare meglio del loop sull'array nel costruttore di Foo e nello che memorizza in modo esplicito zero? La risposta è diversa per std::array?

Normalmente userei un inizializzatore di controventi, ma la lunghezza derivata (che può essere lunga) rende difficile.

Si noti che non è possibile presumere che l'istanza di Foo abbia una durata di memorizzazione statica .

+0

declare come 'std :: atomic atomics_ [kArraySize] = {};'? Non sono sicuro di quali siano le regole per l'inizializzazione atomica –

+0

... È di non fare nulla. Tutto ciò che è statico è inizializzato a zero all'avvio del programma. –

+0

@Ryan Haining: Sì, funziona per un semplice array in stile C. Non sembra funzionare per 'std :: array , N>' sebbene, anche se lo standard sembra dire che dovrebbe. @ n.m .: "Si noti che non posso assumere che l'istanza di Foo abbia una durata di archiviazione statica". – jacobsa

risposta

8

Ok, credo di aver lavorato fino in fondo. Entrambi questi inizializzare tutti i Atomics a zero:

std::atomic<size_t> plain_array[kArraySize] = {}; 
std::array<std::atomic<size_t>, kArraySize> std_array = {}; 

Ecco la logica:

  • [dcl.init.aggr]/1 definisce matrici per essere aggregati.

  • [array.cons]/1 fa sì che std::array sia anche un aggregato.

  • [dcl.init.aggr]/7 dice che se ci sono meno elementi della lista di inizializzazione che ci sono membri dell'aggregato, i rimanenti membri sono inizializzate da una lista di inizializzazione vuota. In questo caso, questo è tutti i membri.

  • [dcl.init.list]/3 definisce lista-inizializzazione da un elenco vuoto per una classe con un costruttore di default (come con std::atomic) per provocare valore di inizializzazione.

  • [dcl.init]/7 indica che le classi senza costruttori forniti dall'utente sono inizializzate a zero. Supponendo che std::array<T> contenga un array di T, e che la rappresentazione a zero di std::atomic<size_t> sia quella che ci aspettiamo, allora siamo a posto.

Ora, std::atomicfa avere un costruttore fornita dall'utente, non solo una fornita dall'utente predefinita costruttore (quest'ultimo è esplicitamente default). Quindi non si adatta tecnicamente alle condizioni dell'ultimo punto. Ma sembra che questo sia uno error nello standard ed è stato fixed nelle bozze più recenti .

Problemi correlati