Inisialisasi default dari std :: array?

104

Dengan C ++ 11 std::array, apakah saya mendapat jaminan bahwa sintaks std::array<T, N> x;akan menginisialisasi semua elemen array secara default?

EDIT : jika tidak, apakah ada sintaks yang akan bekerja pada semua array (termasuk array berukuran nol) untuk menginisialisasi semua elemen ke nilai defaultnya?

EDIT : di cppreference , deskripsi konstruktor default mengatakan:

(constructor) (implicitly declared) (public member function)
default-constructs or copy-constructs every element of the array 

jadi jawabannya mungkin ya. Tapi saya ingin memastikan itu sesuai dengan standar atau standar masa depan.

Vincent
sumber
Menurutku tidak. Ini secara default dideklarasikan sehingga pada dasarnya setara dengan T x[N]sintaks.
Rapptz

Jawaban:

149

Menurut definisi, inisialisasi default adalah inisialisasi yang terjadi ketika tidak ada inisialisasi lain yang ditentukan; bahasa C ++ menjamin Anda bahwa objek apa pun yang tidak Anda berikan penginisialisasi eksplisitnya akan diinisialisasi default (C ++ 11 §8.5 / 11). Itu termasuk objek bertipe std::array<T, N>dan T[N].

Ketahuilah bahwa ada jenis yang inisialisasi defaultnya tidak berpengaruh dan membiarkan nilai objek tidak dapat ditentukan: jenis non-kelas, non-larik (§8.5 / 6). Akibatnya, array objek yang diinisialisasi default dengan tipe seperti itu akan memiliki nilai tak tentu, misalnya:

int plain_int;
int c_style_array[13];
std::array<int, 13> cxx_style_array;

Baik larik gaya-c dan std::arraydiisi dengan bilangan bulat dengan nilai tak tentu, seperti yang plain_intmemiliki nilai tak tentu.

Apakah ada sintaks yang akan bekerja pada semua array (termasuk array berukuran nol) untuk menginisialisasi semua elemen ke nilai defaultnya?

Saya menduga bahwa ketika Anda mengatakan "ke nilai defaultnya" yang Anda maksud adalah "menginisialisasi semua elemen ke T{}". Itu bukan inisialisasi default , ini adalah inisialisasi nilai (8.5 / 7). Anda dapat meminta inisialisasi nilai dengan cukup mudah di C ++ 11 dengan memberikan penginisialisasi kosong pada setiap deklarasi:

int plain_int{};
int c_style_array[13]{};
std::array<int, 13> cxx_style_array{};

Yang akan menginisialisasi nilai semua elemen array secara bergantian, menghasilkan plain_old_int, dan semua anggota dari kedua jenis array, diinisialisasi ke nol.

Casey
sumber
Bagaimana jika itu adalah anggota kelas: struct X {std :: array <int, 12> dozen; X (): dozen () {} Apakah itu memberi saya dua belas nol?
gerardw
4
@gerardw Menurut standar, ya. Berhati-hatilah terhadap bug di MSVC, karena gagal menerapkan beberapa kasus inisialisasi nilai dengan benar.
Casey
1
memang dorongan mengatakan demikian dan mengatasinya dengan boost::value_initialized tautan mereka tetapi saya yakin VC12 (VS2013) memiliki dukungan yang jauh lebih baik sekarang.
v.oddou
1
Membuat saya berharap comitee mengubah standar menjadi inisialisasi nilai default dan merusak nilai sesuai permintaan. Ie std :: array <int, 12> = {std :: undetermined}; atau sesuatu
Viktor Sehr
Dalam praktiknya, apa artinya menginisialisasi sesuatu ke nilai tak tentu? Apa alternatifnya?
Andrew
21

Default-inisialisasi adalah istilah dari Standard yang berpotensi berarti tidak ada inisialisasi sama sekali, jadi yang Anda maksud mungkin adalah inisialisasi nol .

Deskripsi di cppreference.com sebenarnya agak menyesatkan. std::arrayadalah kelas agregat, dan jika jenis elemennya primitif, itu adalah POD: "data lama biasa", dengan semantik yang sangat cocok dengan bahasa C. Konstruktor yang didefinisikan secara implisit std::array< int, N >adalah konstruktor sepele yang sama sekali tidak melakukan apa pun.

Sintaks suka std::array< int, 3 >()atau std::array< int, 3 > x{}yang memberikan nilai nol tidak dilakukan dengan memanggil konstruktor. Mendapatkan nol adalah bagian dari inisialisasi nilai , ditentukan dalam C ++ 11 §8.5 / 8:

Untuk menginisialisasi nilai objek tipe T berarti:

- jika T adalah tipe kelas (mungkin memenuhi syarat cv) tanpa konstruktor default yang disediakan pengguna atau dihapus, maka objek tersebut diinisialisasi nol…, dan jika T memiliki konstruktor default non-sepele, objek tersebut diinisialisasi secara default;

std::arraytidak memiliki konstruktor default yang disediakan pengguna, sehingga inisialisasi nol. Ini memiliki konstruktor default yang didefinisikan secara implisit, tetapi itu sepele, jadi tidak pernah diinisialisasi secara default. (Tapi ini tidak membuat perbedaan karena inisialisasi sepele menurut definisi tidak berpengaruh pada waktu proses.)

jika tidak, apakah ada sintaks yang akan bekerja pada semua array (termasuk array berukuran nol) untuk menginisialisasi semua elemen ke nilai defaultnya?

Array gaya-C dan std::arraykeduanya merupakan agregat, dan cara untuk menginisialisasi semua agregat dengan nol adalah dengan sintaks = {}. Ini berfungsi sejak C ++ 98. Perhatikan bahwa array gaya-C tidak boleh memiliki luas nol, dan itu sizeof (std::array< X, 0 >)bukan nol.

Potatoswatter
sumber
6

Keduanya T x[N];dan std::array<T, N> x;default-inisialisasi setiap elemen array.

Misalnya, jika T = std::string, setiap elemen akan menjadi string kosong. Jika Tkelas tanpa konstruktor default, keduanya akan gagal dikompilasi. Jika T = int, setiap elemen akan memiliki nilai tak tentu (kecuali deklarasi itu kebetulan berada di ruang lingkup namespace)

Cubbi
sumber
0

Pertama-tama, T x [N] tidak menginisialisasi elemen secara default, meskipun inisialisasi default dari skalar tipe T sebenarnya tidak melakukan apa-apa. Di atas juga berlaku untuk std :: array x. Saya pikir yang Anda butuhkan adalah inisialisasi daftar.

Lingxi
sumber