2014-06-19 14 views
8

Powiedzmy mam klasy z tablicy członkowskim std::atomic s, gdzie tablica jest zwymiarowany za pomocą obliczeń (to znaczy może się zmieniać na podstawie innych stałych gdzie indziej w programie):Jak elegancko zainicjować tablicę std :: atomic?

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

Jaki jest najbardziej elegancki sposób, aby upewnić się, że wszystkie atomy zostały zainicjowane na zero? Czy mogę zrobić lepiej niż zapętlanie się tablicy w konstruktorze Foo i jawnie przechowujące zero? Czy odpowiedź różni się dla std::array?

Zwykle użyłbym inicjatora nawiasów klamrowych tutaj, ale długość pochodna (która może być długa) utrudnia.

Należy pamiętać, że nie można założyć, że instancja Foo ma czas przechowywania statycznego .

+0

Zadeklaruj jako 'std :: atomic atomics_ [kArraySize] = {};'? Nie jestem pewien, jakie są reguły dla inicjowania atomów. –

+0

... To nic nie robić. Wszystko statyczne jest inicjowane od zera podczas uruchamiania programu. –

+0

@Ryan Haining: Tak, to działa dla zwykłej tablicy w stylu C. Wydaje się nie działać dla 'std :: array , N>' chociaż, chociaż standard wydaje się mówić, że powinien. @ n.m .: "Nie mogę założyć, że instancja Foo ma czas przechowywania statycznego". – jacobsa

Odpowiedz

8

OK, wydaje mi się, że już to przerabiałem. Oba z nich będzie zainicjować wszystkie z atomistyki do zera:

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

Oto logika:

  • [dcl.init.aggr]/1 określa się tablice agregatów.

  • [array.cons]/1 upoważnia również, że std::array jest agregatem.

  • [dcl.init.aggr]/7 mówi, że jeśli istnieje mniej elementów listy inicjator niż tam są członkami łącznie, następnie pozostali członkowie zostanie zainicjowany z pustą listę inicjatora. W tym przypadku jest to wszystkich członków.

  • [dcl.init.list]/3 określa listę inicjalizację z pustej wykazie klasy z konstruktora domyślnej (jak std::atomic) powoduje wartość inicjalizację.

  • [dcl.init]/7 mówi, że klasy bez konstruktorów dostarczonych przez użytkownika są zero-zainicjowane. Zakładając, że std::array<T> zawiera tablicę T, i że zerowa reprezentacja std::atomic<size_t> jest tym, czego oczekujemy, to jesteśmy dobrzy.

Teraz std::atomicrobi mieć konstruktora użytkownika pod warunkiem, po prostu nie jest użytkownika warunkiem domyślny konstruktora (ten ostatni jest wyraźnie defaulted). Więc to technicznie nie pasuje do warunków ostatniego punktu. Wygląda jednak na to, że jest standardem w wersji error i jest w wersji fixed w nowszych wersjach roboczych .

Powiązane problemy