Ini sebenarnya sangat sulit untuk dijelaskan, tapi saya akan mencobanya ...
Pertama, dimof
memberi tahu Anda dimensi , atau jumlah elemen dalam array. (Saya percaya "dimensi" adalah terminologi yang lebih disukai di lingkungan pemrograman Windows).
Ini perlu karena C++
dan C
tidak memberi Anda cara asli untuk menentukan ukuran array.
Seringkali orang beranggapan sizeof(myArray)
akan bekerja, tetapi itu sebenarnya akan memberi Anda ukuran dalam memori, bukan jumlah elemen. Setiap elemen mungkin membutuhkan lebih dari 1 byte memori!
Selanjutnya, mereka mungkin mencoba sizeof(myArray) / sizeof(myArray[0])
. Ini akan memberikan ukuran dalam memori array, dibagi dengan ukuran elemen pertama. Tidak apa-apa, dan banyak digunakan dalam C
kode. Masalah utama dengan ini adalah bahwa hal itu akan berfungsi jika Anda melewatkan pointer bukan array. Ukuran pointer di memori biasanya akan 4 atau 8 byte, meskipun hal itu menunjuk mungkin menjadi array elemen 1000s.
Jadi hal berikutnya yang harus dicoba C++
adalah menggunakan templat untuk memaksa sesuatu yang hanya berfungsi untuk array, dan akan memberikan kesalahan kompilator pada pointer. Ini terlihat seperti ini:
template <typename T, std::size_t N>
std::size_t ArraySize(T (&inputArray)[N])
{
return N;
}
//...
float x[7];
cout << ArraySize(x); // prints "7"
Template hanya akan berfungsi dengan array. Ini akan menyimpulkan jenis (tidak benar-benar diperlukan, tetapi harus ada di sana untuk mendapatkan template untuk bekerja) dan ukuran array, lalu mengembalikan ukurannya. Cara templat ini ditulis tidak dapat bekerja dengan pointer.
Biasanya Anda bisa berhenti di sini, dan ini ada di C ++ Standard Libary as std::size
.
Peringatan: di bawah sini ia masuk ke wilayah pengacara bahasa berbulu.
Ini cukup keren, tetapi masih gagal dalam kasus tepi yang tidak jelas:
struct Placeholder {
static float x[8];
};
template <typename T, int N>
int ArraySize (T (&)[N])
{
return N;
}
int main()
{
return ArraySize(Placeholder::x);
}
Perhatikan bahwa array x
yang dideklarasikan , tetapi tidak didefinisikan . Untuk memanggil suatu fungsi (yaitu ArraySize
) dengannya, x
harus ditentukan .
In function `main':
SO.cpp:(.text+0x5): undefined reference to `Placeholder::x'
collect2: error: ld returned 1 exit status
Anda tidak dapat menautkan ini.
Kode yang Anda miliki dalam pertanyaan adalah cara mengatasinya. Alih-alih benar-benar memanggil fungsi, kami mendeklarasikan fungsi yang mengembalikan objek dengan ukuran yang tepat . Lalu kami menggunakan sizeof
trik itu.
Ini terlihat seperti kita memanggil fungsi, tetapi sizeof
murni kompilasi waktu konstruksi, sehingga fungsi pernah benar-benar dipanggil.
template <typename T, size_t N>
char(&DimofSizeHelper(T(&array)[N]))[N];
^^^^ ^ ^^^
// a function that returns a reference to array of N chars - the size of this array in memory will be exactly N bytes
Catatan Anda sebenarnya tidak bisa mengembalikan array dari suatu fungsi, tetapi Anda bisa mengembalikan referensi ke array.
Kemudian DimofSizeHelper(myArray)
adalah ekspresi yang tipe array pada N
char
s. Ekspresi sebenarnya tidak harus dapat dijalankan, tetapi masuk akal pada waktu kompilasi.
Karena itu sizeof(DimofSizeHelper(myArray))
akan memberi tahu Anda ukuran pada waktu kompilasi apa yang akan Anda dapatkan jika Anda benar-benar memanggil fungsi tersebut. Meskipun sebenarnya kita tidak menyebutnya.
Jangan khawatir jika blok terakhir itu tidak masuk akal. Ini adalah trik aneh untuk mengatasi kasus tepi yang aneh. Inilah sebabnya mengapa Anda tidak menulis kode semacam ini sendiri, dan biarkan pelaksana perpustakaan khawatir tentang omong kosong semacam ini.
std::array
ataustd::vector
....