C++ Academy · Pelajaran

Pengkhususan Penuh

Sesuaikan templat untuk sesuatu jenis

Pelajaran 1 daripada 413 langkah

Pengkhususan Penuh ialah pelajaran C++ Academy percuma di CoddyKit. Ini ialah pelajaran 1 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran C++ Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus C++ Academy merangkumi sejumlah 4 pelajaran.

Imbas Kembali: Templat

Templat membolehkan satu cebisan kod berfungsi untuk pelbagai jenis. Pengompil menjana versi konkrit bagi setiap jenis yang anda gunakan.

  • Bentuk umum mengendalikan setiap jenis.
  • Kadang-kadang sesuatu jenis memerlukan layanan khusus.
#include <iostream>

template <typename T>
T maxOf(T a, T b) { return a > b ? a : b; }

int main() {
    std::cout << maxOf(3, 9) << ' ' << maxOf(2.5, 1.5) << '\n';
    return 0;
}

Apakah Pengkhususan Penuh?

Pengkhususan penuh menyediakan pelaksanaan yang berasingan sepenuhnya untuk satu jenis tertentu, lalu mengatasi templat umum hanya bagi jenis tersebut.

#include <iostream>

template <typename T>
void describe(T) { std::cout << "some type\n"; }

template <>
void describe(int) { std::cout << "an int\n"; }

int main() {
    describe(3.14);
    describe(42);
    return 0;
}

Sintaks

Pengkhususan penuh bermula dengan kurungan sudut kosong template <> dan menamakan jenis tepat dalam pengkhususan itu.

#include <iostream>

template <typename T>
struct TypeName { static const char* get() { return "unknown"; } };

template <>
struct TypeName<bool> { static const char* get() { return "bool"; } };

int main() {
    std::cout << TypeName<double>::get() << '\n';
    std::cout << TypeName<bool>::get() << '\n';
    return 0;
}

Mengkhususkan Templat Kelas

Templat kelas secara keseluruhan boleh dikhususkan, lalu memberikan sesuatu jenis ahli dan tingkah lakunya sendiri yang berbeza daripada templat utama.

#include <iostream>

template <typename T>
struct Storage {
    T value;
    void show() { std::cout << "value: " << value << '\n'; }
};

template <>
struct Storage<bool> {
    bool value;
    void show() { std::cout << (value ? "true" : "false") << '\n'; }
};

int main() {
    Storage<int> s{5}; s.show();
    Storage<bool> b{true}; b.show();
    return 0;
}

Mengapa Perlu Mengkhususkan?

Pengkhususan mengendalikan jenis yang memerlukan logik berbeza, seperti const char* yang memerlukan perbandingan rentetan dan bukannya perbandingan penuding.

#include <iostream>
#include <cstring>

template <typename T>
bool equal(T a, T b) { return a == b; }

template <>
bool equal(const char* a, const char* b) { return std::strcmp(a, b) == 0; }

int main() {
    std::cout << std::boolalpha;
    std::cout << equal(5, 5) << '\n';
    std::cout << equal("hi", "hi") << '\n';
    return 0;
}

Mengkhususkan Satu Ahli

Bagi templat kelas, anda boleh mengkhususkan hanya satu fungsi ahli untuk jenis tertentu sambil menggunakan semula bahagian yang lain.

#include <iostream>

template <typename T>
struct Printer {
    void print(T v) { std::cout << v << '\n'; }
};

template <>
void Printer<char>::print(char v) {
    std::cout << "char: " << v << '\n';
}

int main() {
    Printer<int>{}.print(7);
    Printer<char>{}.print('A');
    return 0;
}

Padanan Mengatasi Umum

Apabila pengkhususan penuh wujud untuk jenis tepat itu, pengompil sentiasa mengutamakannya berbanding templat utama.

#include <iostream>

template <typename T>
int rank() { return 0; }

template <>
int rank<double>() { return 99; }

int main() {
    std::cout << rank<int>() << ' ' << rank<double>() << '\n';
    return 0;
}

Pengkhususan Mesti Mengikuti Templat Utama

Pengkhususan mesti diisytiharkan selepas templat utama kelihatan; jika tidak, pengompil tidak mempunyai apa-apa untuk dikhususkan.

#include <iostream>

template <typename T>
const char* kind() { return "generic"; }

template <>
const char* kind<float>() { return "float"; }

int main() {
    std::cout << kind<int>() << ' ' << kind<float>() << '\n';
    return 0;
}

Mengkhususkan Templat std

Anda boleh mengkhususkan sesetengah templat pustaka piawai, seperti std::hash, untuk jenis anda sendiri supaya jenis tersebut berfungsi dengan bekas yang menggunakan cincangan.

#include <iostream>

struct Point { int x, y; };

template <typename T>
struct Hasher { size_t operator()(const T&) { return 0; } };

template <>
struct Hasher<Point> {
    size_t operator()(const Point& p) { return p.x * 31 + p.y; }
};

int main() {
    Hasher<Point> h;
    std::cout << h(Point{2, 3}) << '\n';
    return 0;
}

Pengkhususan Nilai

Parameter templat bukan jenis boleh dikhususkan berdasarkan nilai tertentu, yang berguna untuk jadual masa kompilasi.

#include <iostream>

template <int N>
struct Fib { static const int value = Fib<N-1>::value + Fib<N-2>::value; };

template <>
struct Fib<0> { static const int value = 0; };

template <>
struct Fib<1> { static const int value = 1; };

int main() {
    std::cout << Fib<10>::value << '\n';
    return 0;
}

Kekalkan Tingkah Laku yang Konsisten

Pengkhususan hendaklah mengekalkan kontrak konseptual yang sama seperti templat utama; hanya implementation yang berubah. Jika tidak, pemanggil akan terkejut.

#include <iostream>

template <typename T>
T zero() { return T{}; }

template <>
int zero<int>() { return 0; }

int main() {
    std::cout << zero<int>() << ' ' << zero<double>() << '\n';
    return 0;
}

Semakan Ringkas

Uji pemahaman anda tentang sintaks pengkhususan penuh.

Ringkasan

Anda telah mempelajari pengkhususan penuh:

  • menyediakan implementation khusus untuk satu jenis tepat
  • ditulis dengan template <> dan jenis konkrit
  • pengkompil sentiasa mengutamakan pengkhususan tepat
  • berfungsi untuk fungsi, kelas, ahli tunggal dan nilai khusus

Seterusnya, anda akan melihat pengkhususan separa, yang memadankan corak jenis.

Percuma untuk bermula

Pelajari C++ dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
51
Pelajaran
203

Soalan Lazim

Adakah pelajaran “Pengkhususan Penuh” percuma?

Ya — sebanyak 3 pelajaran dalam laluan pembelajaran C++ Academy, termasuk “Pengkhususan Penuh”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus C++ Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Pengkhususan Penuh”?

Sesuaikan templat untuk sesuatu jenis Anda berlatih C++ Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan C++ Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran C++ Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 1 daripada 4.

Berapa lamakah pelajaran “Pengkhususan Penuh” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran C++ Academy ini?

Ya. Setiap pelajaran C++ Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Pengkhususan Penuh
  2. Pengkhususan Separa
  3. SFINAE
  4. Corak enable_if
← Kembali ke C++ Academy