Kita sudah berkenalan dengan using untuk type alias pada Section Variabel dan Tipe Data — di sana alias menyingkat std::vector<std::string> dan kawan-kawannya. Kini setelah struct, enum class, dan union masuk gudang peralatan kita, alias mendapat peran baru yang jauh lebih menarik: memberi nama domain pada tipe komposit. DaftarProduk terbaca lebih bermakna daripada std::vector<Produk>, dan Koordinat lebih menjelaskan maksud daripada Titik yang generik. Pada Chapter ini kita fokus pada alias untuk tipe yang baru saja kita pelajari, mengulang singkat perbandingan using versus typedef, dan menata ulang contoh dari chapter-chapter sebelumnya agar terbaca seperti bahasa domain masalah.

Alias untuk struct dan enum class #

Deklarasinya tetap using nama_baru = tipe_asal; — aturannya tidak berubah, hanya isi sisi kanan yang kini bisa tipe komposit. Alias boleh merujuk struct, enum class, container yang berisi struct, bahkan alias lain; compiler memperlakukan alias dan tipe asalnya sebagai tipe yang identik.

cpp
#include <iostream>
#include <string>
#include <vector>

struct Titik {
    int x;
    int y;
};

enum class StatusKirim { Menunggu, Dikirim, Selesai };

// Alias untuk tipe komposit
using Koordinat = Titik;                        // alias struct
using DaftarKoordinat = std::vector<Titik>;     // alias container berisi struct
using Rute = std::vector<Koordinat>;            // alias dari alias
using Status = StatusKirim;                     // alias enum class

const char* namaStatus(Status s) {
    switch (s) {
    case StatusKirim::Menunggu: return "menunggu";
    case StatusKirim::Dikirim:  return "dikirim";
    case StatusKirim::Selesai:  return "selesai";
    }
    return "tidak dikenal";
}

double jarakManhattan(const Koordinat& a, const Koordinat& b) {
    int dx = a.x > b.x ? a.x - b.x : b.x - a.x;
    int dy = a.y > b.y ? a.y - b.y : b.y - a.y;
    return dx + dy;
}

int main() {
    Rute rute {{0, 0}, {3, 4}, {6, 4}};
    Status kondisi = Status::Dikirim;

    std::cout << "Rute " << rute.size() << " titik, status pengiriman "
              << namaStatus(kondisi) << "\n";
    std::cout << "Jarak titik 1-2: " << jarakManhattan(rute[0], rute[1]) << "\n";
    std::cout << "Jarak titik 2-3: " << jarakManhattan(rute[1], rute[2]) << "\n";

    return 0;
}

Output yang Dihasilkan:

text
Rute 3 titik, status pengiriman dikirim
Jarak titik 1-2: 7
Jarak titik 2-3: 3

Mari kita telaah apa yang terjadi pada baris-baris kode di atas:

  1. Baris 13-16 (using Koordinat = Titik; dst.): empat alias untuk tipe komposit. Rute menunjukkan alias boleh dibangun dari alias lain — compiler mengurai rantai Rute → vector<Koordinat> → vector<Titik> hingga ke tipe aslinya.
  2. Baris 18-25 (const char* namaStatus(Status s)): tanda tangan fungsi memakai alias Status, sehingga pembaca langsung tahu domainnya tanpa perlu tahu nama enum aslinya.
  3. Baris 27-31 (jarakManhattan): parameter const Koordinat& — alias bekerja wajar dengan reference, pass-by-value, dan pass-by-const-reference yang kita kuasai pada Section Fungsi.
  4. Baris 34-35: Rute rute {{0, 0}, {3, 4}, {6, 4}}; — aggregate initialization dan nested init dari chapter-chapter sebelumnya tetap berlaku apa adanya pada tipe alias, karena bagi compiler Rute adalah std::vector<Titik>.

Perhatikan bahwa tidak ada satu pun konversi dalam program ini: rute[0] bertipe Titik, dan fungsi yang menerima const Koordinat& menerimanya tanpa protes — bukti nyata bahwa alias hanyalah nama kedua.

typedef: Sisipan Perbandingan #

Pada Section Variabel dan Tipe Data kita sudah menaruh kesimpulan pentingnya: typedef adalah bentuk lama yang maknanya identik dengan using, tetapi using terbaca dari kiri ke kanan dan hanya using yang bisa dibuat generik (alias template). Pada tipe komposit, keunggulan keterbacaan using makin terasa:

cpp
typedef Titik* PtitikLama;        // gaya lama: nama alias tersembunyi di tengah
using PtitikBaru = Titik*;        // gaya modern: "PtitikBaru adalah Titik*"

typedef int Matriks[3][3];        // typedef pada array terasa rumit
using Matriks2 = int[3][3];       // versi using terbaca kiri ke kanan

Kedua pasangan di atas menghasilkan tipe yang persis sama di mata compiler. Kita tetap perlu membaca typedef karena banyak header lama memakainya, tetapi untuk kode yang kita tulis sendiri, using adalah pilihan baku.

Alias Memperjelas Domain #

Peran terbaik alias pada tipe komposit adalah menyandikan maksud bisnis ke dalam nama tipe. Beberapa pola yang layak dijadikan kebiasaan:

  • Nama koleksi yang bermakna: DaftarProduk, Rute, KamusHarga — jauh lebih informatif daripada std::vector<Produk> yang muncul berulang di sepuluh tanda tangan fungsi.
  • Nama peran domain: Koordinat untuk Titik pada kode grafik, UangCents untuk long long pada kode pembayaran — satu nama, satu konteks pemakaian.
  • Gerbang perubahan: bila Produk berganti menjadi ProdukResmi dengan field berbeda, cukup satu baris alias yang disunting dan seluruh penggunaan DaftarProduk ikut berubah pada kompilasi berikutnya.
  • Menyembunyikan detail platform: alias seperti std::size_t di standard library memakai pola yang sama, sehingga kode kita portabel tanpa menyebut tipe unsigned panjangnya secara eksplisit.

Alias juga menyederhanakan tipe bertingkat dari Chapter Nested Struct: bila Mahasiswa::Alamat dirasa panjang, satu baris using AlamatMhs = Mahasiswa::Alamat; menyingkat seluruh pemakaiannya di luar struct. Bedakan pula dua peran yang bersebelahan ini: struct mendefinisikan tipe baru dengan pemeriksaan tipe sendiri, alias hanya memberi nama baru untuk tipe yang sudah ada — pemilihan di antara keduanya adalah keputusan desain, bukan soal rasa.

Referensi resmi untuk deklarasi alias dapat dibaca pada halaman type alias di cppreference. Chapter penutup Section ini menyingkap fitur yang membuat struct dan pasangan nilai makin enak dipakai: structured bindings, cara mengurai isi struct menjadi beberapa variabel dalam satu baris.