Menu
CoddyTech

Spesialisasi Template

Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan C++ di Coddy. Pelajaran 66 dari 104.

Terkadang, template generik tidak berfungsi dengan baik untuk setiap tipe. Misalnya, membandingkan string bergaya C dengan > membandingkan alamat pointer, bukan teks sebenarnya. Spesialisasi template memungkinkan kamu menyediakan implementasi khusus untuk tipe tertentu, sambil tetap menggunakan versi generik untuk tipe lainnya.

Spesialisasi penuh menggantikan seluruh template untuk satu tipe tertentu. Kamu mendeklarasikannya dengan daftar parameter template kosong dan menentukan tipe konkret:

// Template utama
template <typename T>
class Printer {
public:
    void print(T value) {
        std::cout << value << std::endl;
    }
};

// Spesialisasi penuh untuk const char*
template <>
class Printer<const char*> {
public:
    void print(const char* value) {
        std::cout << "String: " << value << std::endl;
    }
};

Printer<int> intPrinter;
intPrinter.print(42);           // Output: 42

Printer<const char*> strPrinter;
strPrinter.print("hello");      // Output: String: hello

Template fungsi juga dapat dispesialisasi:

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

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

isEqual(5, 5);              // Menggunakan versi generik
isEqual("hi", "hi");        // Menggunakan versi khusus

Compiler selalu memilih kecocokan yang paling spesifik. Jika ada spesialisasi untuk tipe persis yang digunakan, compiler akan memilihnya daripada template generik.

challenge icon

Tantangan

Mudah

Mari buat sistem pemformat yang memahami tipe data untuk menunjukkan bagaimana spesialisasi template memungkinkan kamu menyesuaikan perilaku untuk tipe tertentu sambil mempertahankan fallback generik untuk semua tipe lainnya.

Kamu akan membuat dua file untuk mengatur kode template-mu:

  • Formatter.h: Definisikan template class bernama Formatter yang memformat nilai untuk ditampilkan. Template generikmu harus berfungsi dengan tipe apa pun, tetapi kamu juga akan membuat versi khusus untuk tipe yang memerlukan penanganan khusus.

    Template Formatter utama harus memiliki:

    • method format() yang menerima nilai bertipe T dan mencetak: Value: <value>

    Buat spesialisasi penuh untuk bool yang mencetak teks yang mudah dibaca, bukan 1 atau 0:

    • method format() harus mencetak: Boolean: true atau Boolean: false

    Buat spesialisasi penuh untuk const char* yang menambahkan tanda kutip di sekitar string:

    • method format() harus mencetak: String: "<value>"

    Buat juga template fungsi bernama formatPair yang menerima dua nilai dengan tipe yang sama dan mencetaknya bersama sebagai: Pair: [<first>, <second>]

    Buat spesialisasi formatPair untuk const char* yang membungkus setiap string dengan tanda kutip: Pair: ["<first>", "<second>"]

  • main.cpp: Baca empat input, masing-masing pada baris terpisah:
    1. Sebuah bilangan bulat
    2. Sebuah bilangan desimal
    3. Sebuah boolean dalam bentuk string (true atau false)
    4. Sebuah nilai string

    Tunjukkan cara kerja pemformat dengan membuat object Formatter yang sesuai dan memanggil format() untuk setiap tipe:

    1. Format bilangan bulat menggunakan Formatter<int>
    2. Format bilangan desimal menggunakan Formatter<double>
    3. Format boolean menggunakan Formatter<bool> (ubah input string menjadi bool terlebih dahulu)
    4. Format string menggunakan Formatter<const char*>

    Lalu tunjukkan spesialisasi template fungsi:

    1. Panggil formatPair dengan dua bilangan bulat: 10 dan 20
    2. Panggil formatPair dengan dua C-string: "hello" dan "world"

Sebagai contoh, dengan input 42, 3.14, true, dan Hello:

Value: 42
Value: 3.14
Boolean: true
String: "Hello"
Pair: [10, 20]
Pair: ["hello", "world"]

Perhatikan bagaimana template generik menangani bilangan bulat dan bilangan desimal dengan cara yang sama, sedangkan versi khusus untuk bool dan const char* memberikan pemformatan khusus. Compiler secara otomatis memilih kecocokan yang paling spesifik untuk setiap tipe yang kamu gunakan.

Coba sendiri

#include <iostream>
#include <string>
#include "Formatter.h"

using namespace std;

int main() {
    // Baca input
    int intVal;
    double doubleVal;
    string boolStr;
    string strVal;
    
    cin >> intVal;
    cin >> doubleVal;
    cin >> boolStr;
    cin >> strVal;
    
    // Ubah string menjadi bool
    bool boolVal = (boolStr == "true");
    
    // TODO: Buat Formatter<int> dan format bilangan bulatnya
    
    // TODO: Buat Formatter<double> dan format bilangan desimalnya
    
    // TODO: Buat Formatter<bool> dan format nilai boolean-nya
    
    // TODO: Buat Formatter<const char*> dan format string-nya
    // Petunjuk: Gunakan strVal.c_str() untuk mendapatkan const char*
    
    // TODO: Panggil formatPair dengan dua bilangan bulat: 10 dan 20
    
    // TODO: Panggil formatPair dengan dua C-string: "hello" dan "world"
    
    return 0;
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Object

Latihan sendiri: Compiler C++ online