Belajar C++ - Templates & Generic Programming
Series/Belajar C++/Episode 10
Episode 10 of 24

Belajar C++ - Templates & Generic Programming

Episode ini membahas template sebagai jantung generic programming: function templates dan class templates, template specialization dan variadic templates, concepts dan type traits, serta std::optional dan std::variant untuk nilai opsional dan bervariasi tipe.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Salah satu kekuatan terbesar C++ adalah template: cara menulis kode yang bekerja untuk berbagai tipe data tanpa menduplikasi kode dan tanpa mengorbankan kinerja. Inilah yang membedakan generic programming C++ dari generics di bahasa lain — template dipakai sebagai cetak biru, dan kode nyata dibangkitkan saat kompilasi.

Episode 10 membedah template dari fungsi dan class sederhana, hingga specialization, variadic templates, dan konsep modern seperti concepts dan type traits. Kalian juga akan berkenalan dengan std::optional dan std::variant yang membuat API kalian lebih ekspresif.

Function Template

Satu Fungsi untuk Semua Tipe

Function template memungkinkan satu fungsi bekerja untuk tipe apa pun. Tipe ditentukan saat kompilasi dari argumen yang diberikan:

Function template
cat > fntmpl.cpp <<'EOF'
#include <iostream>
 
template <typename T>
T maksimum(T a, T b) {
    return (a > b) ? a : b;
}
 
int main() {
    std::cout << maksimum(3, 7) << "\n";
    std::cout << maksimum(2.5, 1.8) << "\n";
}
EOF
g++ -std=c++20 fntmpl.cpp -o fntmpl
./fntmpl

template <typename T> T maksimum(T a, T b) mendefinisikan fungsi generik. Saat dipanggil dengan int, compiler membangkitkan versi int; saat dipanggil dengan double, versi double — tanpa overhead runtime.

Deduksi Tipe

Compiler menebak T dari argumen, jadi maksimum(3, 7) menyimpulkan T = int. Jika kedua argumen bertipe berbeda, kalian bisa memaksa dengan maksimum<double>(3, 7). Deduksi bekerja baik selama kedua argumen bertipe sama; jika tidak, butuh dua parameter template atau konversi eksplisit.

Class Template

Kontainer Generik

Class template adalah class yang bertipe parameter. std::vector<int> sebenarnya adalah class template vector<T> dengan T = int. Membuat class template sendiri berguna untuk struktur data yang harus bekerja untuk banyak tipe:

Class template
cat > classtmpl.cpp <<'EOF'
#include <iostream>
#include <string>
 
template <typename T>
class Kotak {
public:
    Kotak(T nilai) : nilai_(nilai) {}
    T nilai() const { return nilai_; }
 
private:
    T nilai_;
};
 
int main() {
    Kotak<int> k1(42);
    Kotak<std::string> k2("halo");
    std::cout << k1.nilai() << " " << k2.nilai() << "\n";
}
EOF
g++ -std=c++20 classtmpl.cpp -o classtmpl
./classtmpl

Kotak<int> k1(42) menginstansiasi class template dengan T = int, dan Kotak<std::string> k2("halo") dengan T = std::string. Dua instansiasi itu adalah dua class berbeda yang masing-masing dibangkitkan saat kompilasi.

Specialization dan Variadic Template

Template Specialization

Template specialization menangani kasus khusus untuk tipe tertentu — kalian bisa menspesialisasikan seluruh template atau hanya sebagian. Contoh: template <> std::string deskripsi<bool>(bool) adalah full specialization untuk bool, dipakai hanya saat T = bool, sementara tipe lain memakai versi generik. Ini berguna ketika perilaku umum tidak cocok untuk tipe tertentu.

Variadic Template

Variadic template menerima jumlah argumen yang tidak tentu dan menjadi dasar fungsi seperti std::printf yang aman tipe. Pola template <typename T, typename... Rest> memisahkan argumen pertama dari sisanya, lalu memanggil dirinya lagi dengan sisa... sampai tidak ada argumen tersisa. Karena kode dibangkitkan untuk setiap kombinasi argumen, pemrosesannya berjalan rekursif.

Concepts dan Type Traits

Constraints dengan Concepts

Sejak C++20, concepts memberi nama pada persyaratan tipe. Dengan concepts, kesalahan template terdeteksi dengan pesan yang jelas, bukan halaman error yang membingungkan:

Concept
cat > concept.cpp <<'EOF'
#include <iostream>
#include <concepts>
 
template <std::integral T>
T ganda(T nilai) {
    return nilai * 2;
}
 
int main() {
    std::cout << ganda(21) << "\n";
}
EOF
g++ -std=c++20 concept.cpp -o concept
./concept

template <std::integral T> membatasi T pada tipe integral seperti int atau long. Memanggil ganda(3.5) menghasilkan error kompilasi yang jelas karena double bukan integral.

Type Traits

Type traits dalam <type_traits> memungkinkan kalian memeriksa dan memodifikasi properti tipe saat kompilasi — std::is_integral_v<T>, std::remove_reference_t<T>, dan sejenisnya memberi introspeksi tipe. Dengan static_assert(std::is_integral_v<int>{:bash} ...), kalian memvalidasi asumsi saat kompilasi; jika gagal, program tidak akan terbuild.

std::optional dan std::variant

Nilai yang Mungkin Kosong

std::optional<T> membungkus nilai T yang mungkin tidak ada dan menggantikan kode klasik yang memakai nilai sentinel seperti -1 atau pointer null. std::nullopt menandakan tidak ada nilai, dan *hasil mengambil nilai yang ada. Tipe fungsi sekarang mengungkapkan kemungkinan kegagalan secara eksplisit.

Nilai dengan Beberapa Kemungkinan Tipe

std::variant<T1, T2, ...> menyimpan satu nilai dari beberapa tipe yang mungkin. Hanya satu alternatif yang aktif pada satu waktu, dan akses diperiksa aman:

std::variant
cat > variant.cpp <<'EOF'
#include <iostream>
#include <variant>
 
int main() {
    std::variant<int, std::string> v;
 
    v = 42;
    std::cout << std::get<int>(v) << "\n";
 
    v = "teks";
    if (auto* p = std::get_if<int>(&v)) {
        std::cout << "int: " << *p << "\n";
    } else {
        std::cout << "bukan int\n";
    }
}
EOF
g++ -std=c++20 variant.cpp -o variant
./variant

std::get_if<int>(&v) mengembalikan pointer ke nilai jika v sedang menyimpan int, atau nullptr jika tidak. variant dan optional membuat kode kalian menyatakan kemungkinan lebih jujur daripada tipe polos.

Penutup

Inti yang harus dibawa pulang:

  • Function template membangkitkan kode per tipe saat kompilasi.
  • Class template seperti Kotak<int> adalah dasar generic programming.
  • Specialization menangani kasus khusus; variadic template menerima argumen banyak.
  • Concepts (C++20) membuat batasan tipe mudah dibaca dan error jelas.
  • Type traits mengintrospeksi properti tipe saat kompilasi.
  • std::optional dan std::variant menyatakan nilai opsional dan multi-tipe dengan aman.

Di episode 11 selanjutnya kita akan membahas error handling dan debugging — exceptions dengan throw dan catch, stack unwinding, jenis exception standar dan custom, debugging dengan GDB dan sanitizers, serta static analysis memakai clang-tidy dan cppcheck.

Belajar C++ - Templates & Generic Programming | Belajar C++