C++26 menyelesaikan proses teknisnya pada pertemuan WG21 Maret 2026 (balot DIS — Draft International Standard — disetujui), dan penerbitan resmi ISO menyusul setelahnya. Bila C++14 dan C++23 berperan sebagai pemoles, C++26 kembali membuka babak baru: reflection saat kompilasi (P2996), contracts untuk syarat prasyarat dan pasca-syarat, dua container baru yaitu std::inplace_vector dan std::hive, pack indexing, serta placeholder variabel _. Karena standar baru saja selesai, dukungan compiler masih berjalan bertahap dan berbeda antar vendor — toolchain course ini (g++ 14.2) belum mendukung satu pun fitur C++26 di atas. Chapter ini memberi peta isinya, contoh bentuk kodenya sebagai blok ilustrasi, dan yang terpenting: cara mengecek sendiri dukungan fitur secara objektif lewat feature-test macro.

Peta Fitur Utama C++26 #

Fitur-fitur terpenting yang diterima ke dalam standar:

  • Reflection (P2996): membaca struktur program — daftar member suatu class, nama enumerator, anotasi — saat kompilasi, lalu menghasilkan kode dari informasi itu. Pengganti resmi untuk banyak trik metaprogramming.
  • Contracts: pre-condition (pre), post-condition (post), dan contract_assert ditulis langsung di kode, dengan mode pemeriksaan yang bisa dikonfigurasi saat build.
  • std::inplace_vector: vector dengan kapasitas tetap di dalam objeknya (tanpa alokasi heap) — pas untuk embedded dan alokasi bebas.
  • std::hive: container dengan pointer/referensi yang stabil saat elemen ditambah-hapus secara acak, berbiaya insert cepat.
  • Pack indexing: menyapa elemen parameter pack secara langsung, T...[0], tanpa trik pemisahan.
  • Placeholder _: variabel sementara tanpa nama yang boleh dipakai berulang — cocok untuk structured binding yang tidak dibaca.

Ilustrasi Kode (Belum Didukung GCC 14) #

Dua contoh berikut adalah bentuk kodenya di C++26 — disajikan sebagai ilustrasi, tanpa klaim bisa dikompilasi di toolchain kita:

cpp Ilustrasi reflection (P2996) — belum didukung GCC 14
#include <meta>

struct Poin { int x; int y; };

constexpr auto anggota = std::meta::nonstatic_data_members_of(^^Poin);
// ^^Poin = "reflection" dari tipe Poin; anggota berisi daftar member
// yang bisa diiterasi saat kompilasi untuk membuat serializer, debug print, dll.
cpp Ilustrasi contracts — belum didukung GCC 14
int bagi(int a, int b)
    pre (b != 0)              // syarat bagi pemanggil
    post (r : r * b == a)     // syarat bagi hasil kembalian
{
    return a / b;
}

Sintaks kedua contoh bisa saja dimodifikasi sebelum ISO menerbitkan teks final, jadi perlakukan contoh ini sebagai peta, bukan API yang beku. Perhatikan juga bahwa reflection membuat banyak makro pembangkit kode tidak diperlukan lagi, dan contracts menggantikan komentar “// b tidak boleh nol” menjadi kontrak yang bisa diperiksa.

Mengecek Dukungan: Feature-Test Macro #

Standar C++ menjanjikan makro praprosesor bernama __cpp_* (bahasa) dan __cpp_lib_* (pustaka). Compiler yang mendukung sebuah fitur wajib mendefinisikan makronya dengan nomor revisi; bila tidak terdefinisi, fitur belum ada. Ini cara objektif mengecek dukungan — lebih bisa dipercaya daripada nomor versi compiler. Program berikut melaporkan kondisi nyata toolchain kita:

cpp
// cek-makro.cpp — mengecek dukungan fitur lewat feature-test macro (cara resmi)
// Kompilasi: g++ -std=c++23 -Wall -Wextra cek-makro.cpp -o cek-makro

#include <iostream>
#include <version>  // deklarasi makro __cpp_lib_* untuk pustaka standar

int main() {
    std::cout << "=== Fitur bahasa ===\n";
#if defined(__cpp_concepts)
    std::cout << "  __cpp_concepts                 = " << __cpp_concepts << "\n";
#endif
#if defined(__cpp_structured_bindings)
    std::cout << "  __cpp_structured_bindings      = " << __cpp_structured_bindings << "\n";
#endif
#if defined(__cpp_designated_initializers)
    std::cout << "  __cpp_designated_initializers  = " << __cpp_designated_initializers << "\n";
#endif
#if defined(__cpp_generic_lambdas)
    std::cout << "  __cpp_generic_lambdas          = " << __cpp_generic_lambdas << "\n";
#endif
#if defined(__cpp_init_captures)
    std::cout << "  __cpp_init_captures            = " << __cpp_init_captures << "\n";
#endif
#if defined(__cpp_multidimensional_subscript)
    std::cout << "  __cpp_multidimensional_subscript = " << __cpp_multidimensional_subscript << "\n";
#endif
#if defined(__cpp_explicit_this_parameter)
    std::cout << "  __cpp_explicit_this_parameter  = " << __cpp_explicit_this_parameter << "\n";
#endif
#if defined(__cpp_if_consteval)
    std::cout << "  __cpp_if_consteval             = " << __cpp_if_consteval << "\n";
#endif
#if defined(__cpp_static_call_operator)
    std::cout << "  __cpp_static_call_operator     = " << __cpp_static_call_operator << "\n";
#endif

    std::cout << "=== Fitur pustaka ===\n";
#if defined(__cpp_lib_ranges)
    std::cout << "  __cpp_lib_ranges               = " << __cpp_lib_ranges << "\n";
#endif
#if defined(__cpp_lib_ranges_to_container)
    std::cout << "  __cpp_lib_ranges_to_container  = " << __cpp_lib_ranges_to_container << "\n";
#endif
#if defined(__cpp_lib_print)
    std::cout << "  __cpp_lib_print                = " << __cpp_lib_print << "\n";
#endif
#if defined(__cpp_lib_expected)
    std::cout << "  __cpp_lib_expected             = " << __cpp_lib_expected << "\n";
#endif
#if defined(__cpp_lib_generator)
    std::cout << "  __cpp_lib_generator            = " << __cpp_lib_generator << "\n";
#endif
#if defined(__cpp_lib_format)
    std::cout << "  __cpp_lib_format               = " << __cpp_lib_format << "\n";
#endif
#if defined(__cpp_lib_span)
    std::cout << "  __cpp_lib_span                 = " << __cpp_lib_span << "\n";
#endif
#if defined(__cpp_lib_three_way_comparison)
    std::cout << "  __cpp_lib_three_way_comparison = " << __cpp_lib_three_way_comparison << "\n";
#endif

    std::cout << "=== Fitur C++26 ===\n";
#if defined(__cpp_pack_indexing)
    std::cout << "  __cpp_pack_indexing            = " << __cpp_pack_indexing << "\n";
#else
    std::cout << "  __cpp_pack_indexing            : belum didukung\n";
#endif
#if defined(__cpp_placeholder_variables)
    std::cout << "  __cpp_placeholder_variables    = " << __cpp_placeholder_variables << "\n";
#else
    std::cout << "  __cpp_placeholder_variables    : belum didukung\n";
#endif
#if defined(__cpp_contracts)
    std::cout << "  __cpp_contracts                = " << __cpp_contracts << "\n";
#else
    std::cout << "  __cpp_contracts                : belum didukung\n";
#endif
#if defined(__cpp_reflection)
    std::cout << "  __cpp_reflection               = " << __cpp_reflection << "\n";
#else
    std::cout << "  __cpp_reflection               : belum didukung\n";
#endif
#if defined(__cpp_lib_inplace_vector)
    std::cout << "  __cpp_lib_inplace_vector       = " << __cpp_lib_inplace_vector << "\n";
#else
    std::cout << "  __cpp_lib_inplace_vector       : belum didukung\n";
#endif
#if defined(__cpp_lib_hive)
    std::cout << "  __cpp_lib_hive                 = " << __cpp_lib_hive << "\n";
#else
    std::cout << "  __cpp_lib_hive                 : belum didukung\n";
#endif
    return 0;
}

Output yang Dihasilkan:

text
=== Fitur bahasa ===
  __cpp_concepts                 = 202002
  __cpp_structured_bindings      = 201606
  __cpp_designated_initializers  = 201707
  __cpp_generic_lambdas          = 201707
  __cpp_init_captures            = 201803
  __cpp_multidimensional_subscript = 202211
  __cpp_explicit_this_parameter  = 202110
  __cpp_if_consteval             = 202106
  __cpp_static_call_operator     = 202207
=== Fitur pustaka ===
  __cpp_lib_ranges               = 202302
  __cpp_lib_ranges_to_container  = 202202
  __cpp_lib_print                = 202211
  __cpp_lib_expected             = 202211
  __cpp_lib_generator            = 202207
  __cpp_lib_format               = 202110
  __cpp_lib_span                 = 202002
  __cpp_lib_three_way_comparison = 201907
=== Fitur C++26 ===
  __cpp_pack_indexing            : belum didukung
  __cpp_placeholder_variables    : belum didukung
  __cpp_contracts                : belum didukung
  __cpp_reflection               : belum didukung
  __cpp_lib_inplace_vector       : belum didukung
  __cpp_lib_hive                 : belum didukung

Mari kita bedah:

  1. Baris 5 (#include <version>): header khusus yang memastikan seluruh makro __cpp_lib_* pustaka terdefinisi — wajib ada sebelum membaca makro pustaka.
  2. Baris 9-35 (fitur bahasa): setiap blok #if defined(...) hanya mencetak bila makro ada. Nilai __cpp_concepts = 202002 berarti dukungan concepts revisi tahun 2020 — angka ini naik ketika fitur direvisi.
  3. Baris 38-60 (fitur pustaka): pola sama untuk pustaka. __cpp_lib_ranges = 202302 menunjukkan libstdc++ 14 sudah pada revisi ranges C++23.
  4. Baris 63-92 (fitur C++26): semua enam makro C++26 jatuh ke cabang #else dan tercetak “belum didukung” — bukti nyata kondisi g++ 14.2, sekaligus pola defensif: kode bisa menyesuaikan diri terhadap compiler yang berbeda.

Membaca Tabel Dukungan Compiler #

Sumber rujukan paling mutakhir untuk “fitur X didukung compiler Y versi Z” adalah halaman C++ compiler support di cppreference . Tabelnya memetakan setiap proposal (dengan nomor Pnnnn) ke kolom GCC, Clang, dan MSVC, lengkap dengan versi pertama yang mendukung dan catatan parsial. Untuk C++26 khususnya, tabel terus bergerak: MSVC biasanya paling cepat, GCC dan Clang mengikuti sambil memperbaiki dukungan pustaka. Kebiasaan yang sehat: tulis kode dengan feature-test macro, pantau tabel untuk merencanakan upgrade, dan jangan mengklaim dukungan fitur dari nama standar saja — C++26 sudah “selesai”, tetapi bukan berarti compiler yang dipakai tim Anda sudah mendukungnya.

Dengan cara cek ini di tangan, kita bisa berani memakai fitur baru tanpa takut salah klaim. Kembali ke materi inti section: chapter berikutnya mendalami uniform initialization — fitur C++11 yang sintaksnya kita sudah pakai sejak awal, lengkap dengan jebakan std::initializer_list-nya.

Rujukan resmi: cppreference — C++26 , cppreference — compiler support , cppreference — feature testing .