pembangunan bahagian belakang
C++
Tutorial Templat C: Bagaimana untuk menggunakan Templat Fungsi dan Kelas?
Tutorial Templat C: Bagaimana untuk menggunakan Templat Fungsi dan Kelas?
Templat ialah mekanisme untuk menjana kod pada masa penyusunan, bukan gula sintaksis; templat fungsi perlu menggunakan parameter T& const, jenis yang dinyatakan secara eksplisit, atau kekangan dua parameter untuk mengelakkan kegagalan derivasi; templat kelas menyokong pengkhususan penuh dan pengkhususan separa, manakala templat fungsi hanya menyokong lebihan beban; takrifan templat mestilah dalam fail pengepala atau dinyatakan secara eksplisit; templat selamat perlu menggunakan konsep atau SFINAE untuk mengekang jenis parameter.

Templat bukan gula sintaks, ia adalah mekanisme untuk menjana kod semasa penyusunan. Jika anda menulis parameter template yang salah, mesej ralat selalunya panjangnya beratus-ratus baris, tetapi puncanya mungkin hanya const& atau typename yang hilang .
Bagaimana untuk menulis templat fungsi supaya tidak tertipu oleh derivasi
Jenis inferens kelihatan mudah, tetapi sebenarnya rapuh. Sebagai contoh, std::max menerima dua parameter. Jika int dan long long dimasukkan, pengkompil tidak boleh menyatukan jenis dan secara langsung melaporkan ralat no matching function .
- Potongan boleh dipintas dengan menyatakan hujah templat secara eksplisit:
max<long long>(a, b)</long> - Gunakan
const T&bukannyaTsebagai parameter untuk mengelakkan penyalinan dan kegagalan derivasi yang tidak perlu (terutamanya untuk objek besar atau kelas tersuai) - Jika anda perlu menyokong penukaran tersirat (seperti
int→double), jangan bergantung pada satu parameter templat. Sebaliknya, gunakan dua parameter bebas dan kekangnya secara manual:templat <typename t typename u><br> auto tambah(T a, U b) -> decltype(ab) { return ab; }</typename>
Pengkhususan templat kelas mesti membezakan antara "pengkhususan penuh" dan "pengkhususan separa"
C tidak membenarkan "lebih muatan" templat kelas selain daripada pengkhususan separa, dan templat fungsi tidak menyokong sebarang bentuk pengkhususan sama sekali - hanya lebihan muatan. Ini amat mengelirukan.
- Pengkhususan penuh: semua parameter templat ditentukan, contohnya
template class Vector<bool> { ... };</bool> - Pengkhususan separa: hanya betulkan beberapa parameter, contohnya,
template <typename t> class Vector<t> { ... };</t></typename>- ini adalah undang-undang; tetapitemplate <typename t> class Vector<t> { ... }</t></typename>ialah takrifan semula, yang menyalahi undang-undang - Pengkhususan separa tidak boleh digunakan dalam templat fungsi. Untuk mencapai kesan yang sama, anda hanya boleh bergantung pada kelebihan beban fungsi atau
if constexpr(sejak C 17)
Mengapa definisi templat tidak boleh diletakkan dalam .cpp
Oleh kerana kod templat tidak menjana kod objek, ia hanya dikembangkan oleh pengkompil semasa instantiasi. Jika pengisytiharan template <typename t> void foo(T x);</typename> diletakkan dalam fail pengepala dan takrifan diletakkan dalam .cpp , dan foo(42) dipanggil selepas fail sumber lain memasukkan fail pengepala, undefined reference to 'foo<int>'</int> akan dilaporkan semasa memaut.
- Terdapat hanya dua penyelesaian: letakkan semua definisi dalam fail pengepala; atau nyatakan versi yang diperlukan secara eksplisit pada penghujung
.cpp, sebagai contoh:templat void foo<int>(int);<br> templat void foo<:string>(std::string);</:string></int>
- Amalan moden cenderung memihak kepada yang pertama (ditakrifkan dalam fail pengepala), digabungkan dengan
inline(boleh digunakan untuk pembolehubah dan templat fungsi bermula dari C 17) untuk mengelakkan pelanggaran ODR - Nota: Walaupun
inlinedigunakan, anda masih perlu memastikan definisi lengkap boleh dilihat di semua titik penggunaan
Perkara yang paling kerap diabaikan ialah had kekangan parameter templat - contohnya, jika anda menulis template <typename t> T square(T x) { return x * x; }</typename> , bolehkah ia menerima std::vector<int></int> ? Pengkompil tidak akan menyekatnya, tetapi ia ranap pada masa jalan. Templat yang benar-benar selamat bergantung pada penapisan manual mengikut concepts (C 20) atau SFINAE, dan bukannya bergantung kepada pengguna untuk lulus jenis yang betul secara sedar.
Atas ialah kandungan terperinci Tutorial Templat C: Bagaimana untuk menggunakan Templat Fungsi dan Kelas?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!
Alat AI Hot
Undress AI Tool
Gambar buka pakaian secara percuma
AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.
Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik
Stock Market GPT
Penyelidikan pelaburan dikuasakan AI untuk keputusan yang lebih bijak
Artikel Panas
Alat popular
Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma
SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan
Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa
Dreamweaver CS6
Alat pembangunan web visual
SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)
Topik panas
Bagaimana untuk menukar tatasusunan char kepada rentetan dalam C? (Penukaran jenis)
Mar 06, 2026 am 02:31 AM
Cara paling langsung untuk menukar tatasusunan char kepada rentetan menggunakan pembina std::string adalah dengan menyerahkan rentetan gaya C berterusan (berakhir dengan '\0') kepada std::string untuk pengurusan. Cara paling selamat ialah memanggil pembinanya: chaarr[]="hello";std::strings(arr); Baris kod ini akan berhenti secara automatik apabila ia berbunyi '\0' dan tidak perlu melepasi panjang secara manual. Tetapi premisnya ialah arr berakhir dengan '\0' - jika tatasusunan tindanan yang tidak dimulakan, atau serpihan yang dipotong daripada data binari, ia mungkin membaca memori di luar had. Jika tatasusunan tidak mengandungi '\0' (contohnya, anda hanya menggunakan 5 aksara pertama
Bagaimana untuk memformat output dalam C? (std::tetapan ketepatan cout)
Mar 06, 2026 am 02:34 AM
Gunakan std::fixed dengan std::setprecision untuk menetapkan bilangan tempat perpuluhan; std::fixed melumpuhkan notasi saintifik, dan setprecision(n) mewakili n digit selepas titik perpuluhan di bawah tetap; #include diperlukan; untuk mengelakkan pencemaran keadaan global, bendera dan ketepatan harus disimpan dan dipulihkan, atau diformat secara berasingan dengan aliran ostring.
Bagaimana untuk membetulkan kesalahan segmentasi dalam C? (Penyahpepijatan memori)
Mar 05, 2026 am 01:50 AM
Kesalahan pembahagian biasanya tidak disebabkan oleh kod yang ditulis secara salah, tetapi oleh ingatan yang dipijak. Sebab di sebalik kebanyakan kesalahan segmentasi (terutamanya yang tiba-tiba ranap semasa masa jalan dan tidak mempunyai garis ralat yang jelas) bukanlah kerana penunjuk tidak dimulakan, tetapi ia telah ditulis di luar sempadan, digunakan selepas pelepasan, atau limpahan tindanan - titik di mana ralat berlaku dan titik pemusnahan selalunya berpuluh-puluh baris atau malah berbilang fungsi. Sukar untuk mengesan malloc/baru dengan mengimbasnya dengan mata kasar. Menyusun sekali dengan AddressSanitizer lebih dipercayai daripada menyahpepijat printf selama tiga jam. Ia bukan "alat tambahan", tetapi pengesan ralat memori terbina dalam dalam pengkompil. Ia boleh menunjukkan secara langsung baris mana yang menulis alamat haram, yang mengeluarkan penunjuk liar, dan tatasusunan yang melebihi beberapa bait. GCC
Bagaimana untuk menggunakan kata kunci auto dalam C? (Taip inferens)
Mar 05, 2026 am 02:43 AM
Apabila tiba masanya untuk menggunakan auto dan bukannya jenis tulisan tangan: jenis ungkapan diketahui dan nama jenisnya panjang (seperti iterator, nilai pulangan lambda, jenis templat bersarang), yang boleh mengelakkan ralat ejaan dan meningkatkan kebolehselenggaraan; kecuali untuk parameter fungsi, pembolehubah ahli kelas dan antara muka yang memerlukan semantik yang jelas.
Bagaimana untuk mengisih vektor dalam C? (std::algoritma isihan)
Mar 06, 2026 am 02:08 AM
std::sort lalai kepada tertib menaik kerana penggunaan operator
Bagaimana untuk memautkan perpustakaan luaran dalam C? (Pepautan statik lwn Dinamik)
Mar 05, 2026 am 02:46 AM
Pustaka pautan statik mesti diletakkan selepas fail sumber dan perpustakaan dinamik perlu dikonfigurasikan dengan laluan masa jalan atau perpustakaan standard pautan statik. Apabila ABI tidak sepadan, anda harus mengelak daripada menaik taraf pustaka sistem dan sebaliknya gunakan -static-libstdc atau kompilasi cermin lama.
Bagaimana untuk menggunakan std::optional dalam C ? (Mengendalikan nilai yang hilang)
Mar 05, 2026 am 02:50 AM
std::optional ialah alat keselamatan jenis yang digunakan untuk menyatakan dengan jelas bahawa nilai itu mungkin tidak wujud. Ia sesuai untuk senario di mana hasil pengembalian fungsi mungkin tidak sah (seperti pembahagian dengan sifar, kegagalan penghuraian), dan bukannya menggantikan penunjuk atau menguruskan memori timbunan; pelarasan telanjang nilai() harus dielakkan dan value_or() atau has_value() hendaklah digunakan terlebih dahulu untuk menyemak. Inisialisasi eksplisit disyorkan semasa pembinaan dan std::nullopt digunakan untuk pembersihan.
Bagaimana untuk mengira faktorial nombor dalam C? (Logik rekursi)
Mar 05, 2026 am 02:24 AM
Pengiraan faktor rekursif paling kerap ranap disebabkan pengendalian sempadan yang salah. Contohnya, apabila n==0 atau n==1, rekursi berterusan tanpa mengembalikan 1, mengakibatkan panggilan tak terhingga dan limpahan tindanan; C tidak dipotong secara automatik, dan huruf asas mesti ditulis dengan jelas: if(n





