std::array
jauh lebih unggul dari array C. Dan bahkan jika saya ingin bekerja sama dengan kode lama, saya cukup menggunakan std::array::data()
. Apakah ada alasan mengapa saya menginginkan array jadul?
std::array
jauh lebih unggul dari array C. Dan bahkan jika saya ingin bekerja sama dengan kode lama, saya cukup menggunakan std::array::data()
. Apakah ada alasan mengapa saya menginginkan array jadul?
Jawaban:
Kecuali saya telah melewatkan sesuatu (saya tidak mengikuti perubahan terbaru dalam standar terlalu dekat), sebagian besar penggunaan array gaya C masih tetap ada. std::array
memungkinkan inisialisasi statis, tetapi masih tidak akan menghitung penginisialisasi untuk Anda. Dan karena satu-satunya penggunaan sebenarnya dari array gaya C sebelumnya std::array
adalah untuk tabel yang diinisialisasi secara statis di sepanjang baris:
MyStruct const table[] =
{
{ something1, otherthing1 },
// ...
};
menggunakan fungsi biasa begin
dan end
template (diadopsi dalam C ++ 11) untuk mengulanginya. Tanpa pernah menyebutkan ukuran, yang ditentukan oleh compiler dari jumlah penginisialisasi.
EDIT: Hal lain yang saya lupa: string literal masih array gaya C; yaitu dengan tipe char[]
. Saya tidak berpikir ada orang yang akan mengecualikan penggunaan string literal hanya karena kita punya std::array
.
const char[]
Tidak Untuk, uh, terus terang. Dan dalam 30 karakter.
Tentu saja, Anda memerlukan array C untuk diimplementasikan std::array
, tetapi itu sebenarnya bukan alasan bahwa pengguna menginginkan array C. Selain itu, tidak, std::array
performanya tidak kalah dengan array C, dan memiliki opsi untuk akses yang diperiksa batasnya. Dan akhirnya, sangat masuk akal untuk program C ++ apa pun untuk bergantung pada pustaka Standar- itulah intinya adalah Standar- dan jika Anda tidak memiliki akses ke pustaka Standar, maka kompiler Anda tidak sesuai dan pertanyaan diberi tag "C ++", bukan "C ++ dan hal-hal bukan-C ++ yang kehilangan separuh spesifikasi karena merasa tidak sesuai.".
std::array
dalam implementasi C ++ 11 yang berdiri sendiri.
Sepertinya menggunakan multi-dimensi array lebih mudah dengan C array dari std::array
. Contohnya,
char c_arr[5][6][7];
sebagai lawan
std::array<std::array<std::array<char, 7>, 6>, 5> cpp_arr;
Juga karena properti peluruhan otomatis dari array C, c_arr[i]
dalam contoh di atas akan meluruh menjadi penunjuk dan Anda hanya perlu meneruskan dimensi yang tersisa sebagai dua parameter lagi. Maksud saya c_arr
adalah tidak mahal untuk menyalin. Namun, cpp_arr[i]
akan sangat mahal untuk menyalinnya.
array
ke fungsi tanpa kehilangan dimensi. Dan jika Anda meneruskannya ke template fungsi, maka fungsi tersebut dapat menyimpulkan dimensi dan ukuran setiap dimensi, atau hanya salah satu dari keduanya. Ini mungkin menarik untuk pustaka template ilmiah yang pada prinsipnya bekerja pada dimensi arbitrer.
template <typename T, int M, int N> using array2d = std::array<std::array<T, N>, M>;
harus menyelesaikan salah satu dari masalah tersebut.
c_arr
adalah sangat mahal untuk menyalin! Anda harus memberikan kode untuk melakukannya sendiri. Penunjuk yang akan meluruhnya lebih mirip dengan referensi daripada salinan dan Anda dapat menggunakan std::array
untuk meneruskan referensi jika itu yang Anda inginkan.
std::size_t
bukan int
? maaf untuk nitpicking, tapi ini akan membuatnya universal.
size_t
jika Anda mau, walaupun saya tidak dapat membayangkan ada banyak skenario di mana diperlukan array dengan lebih dari 4 miliar baris atau kolom.
Seperti yang dikatakan Sumant, array multi-dimensi jauh lebih mudah digunakan dengan array-C bawaan daripada dengan std::array
.
Saat bersarang, std::array
bisa menjadi sangat sulit untuk dibaca dan bertele-tele yang tidak perlu.
Sebagai contoh:
std::array<std::array<int, 3>, 3> arr1;
dibandingkan dengan
char c_arr[3][3];
Juga, perhatikan itu begin()
, end()
dan size()
semua mengembalikan nilai yang tidak berarti saat Anda menumpuk std::array
.
Untuk alasan ini saya telah membuat wadah array multidimensi ukuran tetap saya sendiri, array_2d
dan array_3d
. Mereka analog std::array
tetapi untuk array multidimensi 2 dan 3 dimensi. Mereka lebih aman dan tidak memiliki kinerja yang lebih buruk daripada array multidimensi bawaan. Saya tidak menyertakan wadah untuk array multidimensi dengan dimensi lebih besar dari 3 karena tidak umum. Dalam C ++ 0x, versi template variadic dapat dibuat yang mendukung jumlah dimensi yang berubah-ubah.
Contoh varian dua dimensi:
//Create an array 3 x 5 (Notice the extra pair of braces)
fsma::array_2d <double, 3, 5> my2darr = {{
{ 32.19, 47.29, 31.99, 19.11, 11.19},
{ 11.29, 22.49, 33.47, 17.29, 5.01 },
{ 41.97, 22.09, 9.76, 22.55, 6.22 }
}};
Dokumentasi lengkap tersedia di sini:
http://fsma.googlecode.com/files/fsma.html
Anda dapat mengunduh perpustakaan di sini:
arr[x][y]
, Anda tidak dapat membedakan apakah arr
array array, array pointer, pointer ke array, atau pointer ke pointer; semua untuk implementasi sah, tergantung pada kebutuhan Anda. Dan mungkin sebagian besar kasus penggunaan dunia nyata untuk array multidimensi memerlukan ukuran yang ditentukan pada waktu proses.
Array C-style yang tersedia di C ++ sebenarnya jauh lebih tidak fleksibel daripada C-array yang sebenarnya. Perbedaannya adalah, di C, tipe array bisa memiliki ukuran runtime . Berikut ini adalah kode C yang valid, tetapi tidak dapat diekspresikan dengan larik gaya C ++ C maupun dengan jenis C ++ array<>
:
void foo(int bar) {
double tempArray[bar];
//Do something with the bar elements in tempArray.
}
Di C ++, Anda harus mengalokasikan array sementara di heap:
void foo(int bar) {
double* tempArray = new double[bar];
//Do something with the bar elements behind tempArray.
delete[] tempArray;
}
Ini tidak dapat dicapai dengan std::array<>
, karena bar
tidak diketahui pada waktu kompilasi, ini memerlukan penggunaan array gaya-C di C ++ atau dari std::vector<>
.
Sementara contoh pertama relatif mudah diekspresikan dalam C ++ (meskipun membutuhkan new[]
dan delete[]
), berikut ini tidak dapat dicapai dalam C ++ tanpa std::vector<>
:
void smoothImage(int width, int height, int (*pixels)[width]) {
int (*copy)[width] = malloc(height*sizeof(*copy));
memcpy(copy, pixels, height*sizeof(*copy));
for(y = height; y--; ) {
for(x = width; x--; ) {
pixels[y][x] = //compute smoothed value based on data around copy[y][x]
}
}
free(copy);
}
Intinya adalah, pointer ke line array int (*)[width]
tidak dapat menggunakan lebar runtime di C ++, yang membuat kode manipulasi gambar menjadi jauh lebih rumit di C ++ daripada di C. Implementasi C ++ khas dari contoh manipulasi gambar akan terlihat seperti ini:
void smoothImage(int width, int height, int* pixels) {
int* copy = new int[height*width];
memcpy(copy, pixels, height*width*sizeof(*copy));
for(y = height; y--; ) {
for(x = width; x--; ) {
pixels[y*width + x] = //compute smoothed value based on data around copy[y*width + x]
}
}
delete[] copy;
}
Kode ini melakukan penghitungan yang persis sama dengan kode C di atas, tetapi kode ini perlu melakukan penghitungan indeks secara manual di mana pun indeks digunakan . Untuk kasus 2D, hal ini masih dapat dilakukan (meskipun memiliki banyak peluang untuk salah menghitung indeks). Ini menjadi sangat buruk dalam kasus 3D.
Saya suka menulis kode dalam C ++. Tetapi setiap kali saya perlu memanipulasi data multidimensi, saya benar-benar bertanya pada diri sendiri apakah saya harus memindahkan bagian kode itu ke C.
gcc
misalnya). C11 telah membuat beberapa hal menarik menjadi opsional, dan saya rasa itu bukan karena mereka ingin melarang fitur tersebut. Saya cenderung melihatnya sebagai tanda bahwa mereka ingin menurunkan level untuk menulis kompiler yang memenuhi standar sepenuhnya: VLA adalah binatang yang cukup sulit untuk diterapkan, dan banyak kode dapat melakukannya tanpa, jadi masuk akal untuk kompiler baru pada beberapa yang baru platform untuk tidak harus segera mengimplementasikan VLA.
Mungkin std::array
tidak lambat. Tapi saya melakukan beberapa benchmarking menggunakan simple store dan membaca dari std :: array; Lihat hasil benchmark di bawah ini (pada W8.1, VS2013 Update 4):
ARR_SIZE: 100 * 1000
Avrg = Tick / ARR_SIZE;
test_arr_without_init
==>VMem: 5.15Mb
==>PMem: 8.94Mb
==>Tick: 3132
==>Avrg: 0.03132
test_arr_with_init_array_at
==>VMem: 5.16Mb
==>PMem: 8.98Mb
==>Tick: 925
==>Avrg: 0.00925
test_arr_with_array_at
==>VMem: 5.16Mb
==>PMem: 8.97Mb
==>Tick: 769
==>Avrg: 0.00769
test_c_arr_without_init
==>VMem: 5.16Mb
==>PMem: 8.94Mb
==>Tick: 358
==>Avrg: 0.00358
test_c_arr_with_init
==>VMem: 5.16Mb
==>PMem: 8.94Mb
==>Tick: 305
==>Avrg: 0.00305
Menurut tanda negatifnya, kode yang saya gunakan ada di pastebin ( tautan )
Kode kelas patokan ada di sini ;
Saya tidak tahu banyak tentang pembandingan ... Kode saya mungkin cacat
long test_arr_without_init() { return ARR_SIZE; }
void test_arr_without_init() {}
sekarang. Anda benar-benar perlu melewati rintangan untuk memastikan kode yang Anda ukur adalah kode yang ingin Anda ukur.
std::array
std::array
akan menjadi kurang berkinerja dari array C.
at()
, tidak masuk operator[]
, sama seperti std::vector
. Tidak ada penurunan kinerja atau kode yang membengkak std::array
, kompilator dirancang untuk mengoptimalkan hal semacam ini. Dan, tentu saja, penambahan fungsi yang dicentang merupakan alat debug yang sangat baik dan keuntungan besar. @ Lou Franco: Semua kode C ++ mungkin bergantung pada pustaka Standar- untuk itulah. @Earlz: Jika Anda tidak memiliki STL yang tersedia, maka itu bukan C ++, dan itulah akhir dari itu.
std::array
agar lebih besar dari penggunaan array C yang setara.