Selamat siang, pembaca yang budiman!
Artikel ini adalah yang kedua dari serangkaian artikel abstrak yang akan saya tulis ketika saya membaca buku terlaris Scott Meyers, Effective and Modern c ++. Setiap artikel ini akan memiliki direktori terpisah dalam proyek yang khusus dibuat di github.com dengan contoh langsung menggunakan apa yang kita baca hari ini.
Artikel ini melengkapi aturan inferensi tipe dari artikel sebelumnya dan membahas aspek-aspek tertentu dari inferensi tipe template untuk argumen yang berupa array dan fungsi.
Inferensi tipe pola untuk array
Kompilator c ++ memiliki properti sedemikian sehingga array yang dideklarasikan selalu, ketika diteruskan ke fungsi templat dengan parameter yang dinyatakan bukan sebagai tautan, selalu dikonversi menjadi pointer ke tipe yang disimpan dan sebaliknya, jika parameter tersebut dinyatakan sebagai tautan, maka konversi tersebut tidak dilakukan.
Fungsi Templat:
Untuk memulainya, saya akan memberikan kode fungsi templat yang menyimpulkan tipe-tipe yang didambakan, dan kemudian proses derivasi itu sendiri:
template<typename T> void paramDeductInfo(T param, const char *initType) { std::cout << initType << " -> (T param) -> " << type_id_with_cvr<T>().pretty_name() << std::endl; }; template<typename T> void refParamDeductInfo(T ¶m, const char *initType) { std::cout << initType << " -> (T ¶m) -> " << type_id_with_cvr<T>().pretty_name() << std::endl; };
Jenis Inferensi:
cli::printCaption("TYPE DEDUCTION FOR ARRAY OF CHAR"); char charSeq[] = "Hi everyone!"; paramDeductInfo(charSeq, "char []"); refParamDeductInfo(charSeq, "char []"); cli::printCaption("TYPE DEDUCTION FOR ARRAY OF INT"); int intSeq[] = {1, 2, 3}; paramDeductInfo(intSeq, "int []"); refParamDeductInfo(intSeq, "int []"); cli::printCaption("TYPE DEDUCTION FOR ARRAY OF CLASS A"); class A { } const classASeq[] = {A(), A(), A()}; paramDeductInfo(classASeq, "class A[]"); refParamDeductInfo(classASeq, "class A[]");
Kode pseudo berikut mencerminkan output ke konsol dari instruksi ini:
************************************************************************************************************************ TYPE DEDUCTION FOR ARRAY OF CHAR ************************************************************************************************************************ char [] -> (T param) -> char* char [] -> (T ¶m) -> char [13] ************************************************************************************************************************ TYPE DEDUCTION FOR ARRAY OF INT ************************************************************************************************************************ int [] -> (T param) -> int* int [] -> (T ¶m) -> int [3] ************************************************************************************************************************ TYPE DEDUCTION FOR ARRAY OF CLASS A ************************************************************************************************************************ class A[] -> (T param) -> main::A const* class A[] -> (T ¶m) -> main::A const [3]
Contoh 1 - menganalisis panjang array waktu kompilasi
Selain itu, tipe output array menyimpan informasi tentang ukurannya, yang dapat digunakan dalam fungsi template untuk memanipulasi ukuran array selama kompilasi atau untuk menghasilkan kode yang lebih efisien.
Saya menggunakan fitur ini dalam fungsi printCaption untuk membatasi panjang header yang ditampilkan pada baris perintah pada waktu kompilasi. Agak, tapi bagus.
namespace cli { template<typename T, std::size_t N> constexpr void printCaption(T (&capValue)[N]) { static_assert(N <= 121, "caption length should be less than 120"); std::cout << std::endl << "*******************************************************************************" << std::endl << capValue << std::endl << "*******************************************************************************" << std::endl << std::endl; }; }
Mari kita periksa apakah akan ada kesalahan jika kita memperkenalkan tajuk yang jelas tidak pantas.
cli::printCaption("123456789 123456789 123456789 123456789 123456789 123456789 123456789" "123456789 123456789 123456789 123456789 123456789 !");
Dan di sini Anda, tolong, well, bukankah ini luar biasa?
/...sources/cli.h:12:3: error: static assertion failed: caption length should be less than 120 static_assert(N <= 121, "caption length should be less than 120"); ^~~~~~~~~~~~~
Contoh 2 - foreach pada array di memori
Saya pikir di sini adalah pendekatan lain yang mungkin tampak berguna jika kita memiliki ukuran array dalam waktu kompilasi, mengapa tidak menggunakannya untuk mengatur loop pada array seperti itu?
template<typename T, size_t N, typename F> void forEachOnAnArray(T (&inmemArray)[N], F &callback) { for (int i = 0; i < N; ++i) callback(inmemArray[i]); };
Menggunakan fungsi ini adalah sebagai berikut:
auto printInt = [](int value) { std::cout << " " << value; }; forEachOnAnArray(intSeq, printInt);
Secara umum, menggunakan fitur ini tidak terbatas untuk menarik keluar ukuran array.
Ketik inferensi untuk suatu fungsi
Berbicara tentang inferensi tipe untuk fungsi Meyers ringkas. Ia menyebutkan dengan tepat bahwa mereka direduksi menjadi sebuah pointer dengan cara yang sama seperti untuk array, kecuali ketika parameter fungsi template yang digunakan untuk menampilkan tipe fungsi kami tidak dinyatakan sebagai tautan.
Dia mungkin seharusnya berbicara tentang beberapa jenis pembungkus template untuk fungsi, tapi saya kira itu melampaui pertanyaan tentang c ++ yang efisien dan modern.
Kami, pembaca yang budiman, pasti akan kembali ke masalah ini!
Terima kasih dan semoga harimu menyenangkan !!