Rozważać:
void foo() {
std::vector<std::atomic<int>> foo(10);
...
}
Czy zawartość foo jest teraz aktualna? Czy też muszę je przejrzeć i zainicjować? Sprawdziłem Godbolt i wydaje się, że jest w porządku, jednak standard wydaje się być bardzo zagmatwany w tym punkcie.
Konstruktor std :: vector mówi, że wstawia instancje wstawione domyślniestd::atomic<int>
, których wartość jest inicjowana poprzez umieszczenie new
.
Myślę, że ten efekt inicjalizacji wartości ma zastosowanie:
2) jeśli T jest typem klasy z domyślnym konstruktorem, który nie jest ani dostarczony przez użytkownika, ani usunięty (to znaczy może to być klasa z domyślnie zdefiniowanym lub domyślnym konstruktorem domyślnym), obiekt jest inicjowany na zero, a następnie jest default-initialized, jeśli ma nietrywialny domyślny konstruktor;
Wydaje mi się więc, że atomika jest inicjowana na zero. Pytanie brzmi zatem: czy inicjalizacja zera std::atomic<int>
wyniku jest poprawnym obiektem?
Zgaduję, że odpowiedź brzmi „tak w praktyce, ale nie jest tak naprawdę zdefiniowana”?
Uwaga: Ta odpowiedź zgadza się, że jest inicjowana na zero, ale tak naprawdę nie mówi, czy to oznacza, że obiekt jest poprawny.
atomic_init
. W każdym razie musisz już zsynchronizować kod w pytaniuNawet jeśli został wywołany domyślny konstruktor (nie jest, ponieważ jest trywialny) , tak naprawdę nic nie robi .
Nie można oczywiście zagwarantować, że zerowa inicjalizacja wytworzy prawidłowy atom; zadziała to tylko wtedy, gdy przypadkowo powstanie prawidłowy atom, inicjując zero wszystkich jego członków.
A ponieważ atomów nie można kopiować, nie można podać wartości inicjalizacyjnej w konstruktorze wektorowym.
Powinieneś teraz zapętlić pojemnik i
std::atomic_init
każdy element. Jeśli musisz to zablokować, to dobrze, ponieważ już synchronizujesz tworzenie wektora z tego samego powodu.źródło