Czy w przypadku C ++ 11 std::array
mam gwarancję, że składnia std::array<T, N> x;
będzie domyślnie inicjowała wszystkie elementy tablicy?
EDYCJA : jeśli nie, czy istnieje składnia, która będzie działać na wszystkich tablicach (w tym tablicach o rozmiarze zerowym), aby zainicjować wszystkie elementy do ich wartości domyślnych?
EDYCJA : w cppreference , domyślny opis konstruktora mówi:
(constructor) (implicitly declared) (public member function)
default-constructs or copy-constructs every element of the array
więc odpowiedź może brzmieć tak. Ale chciałbym być tego pewien zgodnie ze standardem lub przyszłym standardem.
T x[N]
składni.Odpowiedzi:
Z definicji inicjalizacja domyślna to inicjalizacja, która ma miejsce, gdy nie określono żadnej innej inicjalizacji; język C ++ gwarantuje, że każdy obiekt, dla którego nie podasz jawnego inicjatora, zostanie domyślnie zainicjowany (C ++ 11 §8.5 / 11). Obejmuje to obiekty typu
std::array<T, N>
iT[N]
.Należy pamiętać, że istnieją typy, dla których domyślna inicjalizacja nie ma wpływu i pozostawia nieokreśloną wartość obiektu: dowolny typ niebędący klasą, nie tablicowy (§8.5 / 6). W konsekwencji, domyślnie zainicjowana tablica obiektów o takich typach będzie miała nieokreśloną wartość, np .:
Zarówno tablica w stylu c, jak i
std::array
są wypełnione liczbami całkowitymi o nieokreślonej wartości, tak jakplain_int
ma nieokreśloną wartość.Domyślam się, że kiedy mówisz „do ich wartości domyślnej”, naprawdę masz na myśli „zainicjuj wszystkie elementy na
T{}
”. To nie jest inicjalizacja domyślna , jest to inicjalizacja wartości (8.5 / 7). Możesz łatwo zażądać inicjalizacji wartości w C ++ 11, nadając każdej deklaracji pusty inicjator:Który z kolei zainicjuje wartość i wartość wszystkich elementów tablicy, w wyniku czego
plain_old_int
wszystkie elementy członkowskie obu rodzajów tablic zostaną zainicjowane na zero.źródło
boost::value_initialized
łącza, ale uważam, że VC12 (VS2013) ma teraz znacznie lepsze wsparcie.Inicjalizacja domyślna to termin ze Standardu, który potencjalnie oznacza brak inicjalizacji, więc prawdopodobnie masz na myśli inicjalizację zerową .
Opis na cppreference.com jest w rzeczywistości nieco mylący.
std::array
jest klasą zagregowaną, a jeśli typ elementu jest prymitywny, to jest to POD: „zwykłe stare dane” z semantyką ściśle dopasowaną do języka C. Niejawnie zdefiniowany konstruktor programustd::array< int, N >
jest trywialny i nie robi absolutnie nic.Składnia taka jak
std::array< int, 3 >()
lub,std::array< int, 3 > x{}
która zapewnia zerowe wartości, nie robi tego przez wywołanie konstruktora. Pobieranie zer jest częścią inicjalizacji wartości , określonej w C ++ 11 §8.5 / 8:std::array
nie ma domyślnego konstruktora dostarczonego przez użytkownika, więc jest inicjowany przez zero. Ma domyślnie zdefiniowany konstruktor domyślny, ale jest trywialny, więc nigdy nie jest inicjowany domyślnie. (Ale to nie robi różnicy, ponieważ trywialna inicjalizacja z definicji nie ma wpływu na środowisko wykonawcze).Tablice w stylu C i
std::array
oba są agregatami, a sposobem na całkowicie zerową inicjalizację dowolnej agregacji jest składnia= {}
. Działa to od C ++ 98. Zauważ, że tablice w stylu C nie mogą mieć zerowego zasięgu, asizeof (std::array< X, 0 >)
to nie jest zero.źródło
Zarówno, jak
T x[N];
istd::array<T, N> x;
domyślnie inicjalizuj każdy element tablicy.Na przykład, jeśli
T = std::string
każdy element będzie pustym ciągiem. JeśliT
jest to klasa bez domyślnego konstruktora, obie nie będą mogły się skompilować. JeśliT = int
każdy element będzie miał nieokreśloną wartość (chyba że ta deklaracja znajduje się w zakresie przestrzeni nazw)źródło
Po pierwsze, T x [N] domyślnie inicjalizuje elementy, chociaż domyślna inicjalizacja typu skalarnego T w rzeczywistości nic nie robi. Powyższe dotyczy również std :: array x. Myślę, że potrzebujesz inicjalizacji listy.
źródło
C ++ 11 std :: array :: fill jest dobrą opcją w niektórych przypadkach.
źródło