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), dancontract_assertditulis 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:
#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.
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:
// 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:
=== 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 didukungMari kita bedah:
- Baris 5 (
#include <version>): header khusus yang memastikan seluruh makro__cpp_lib_*pustaka terdefinisi — wajib ada sebelum membaca makro pustaka. - Baris 9-35 (fitur bahasa): setiap blok
#if defined(...)hanya mencetak bila makro ada. Nilai__cpp_concepts = 202002berarti dukungan concepts revisi tahun 2020 — angka ini naik ketika fitur direvisi. - Baris 38-60 (fitur pustaka): pola sama untuk pustaka.
__cpp_lib_ranges = 202302menunjukkan libstdc++ 14 sudah pada revisi ranges C++23. - Baris 63-92 (fitur C++26): semua enam makro C++26 jatuh ke cabang
#elsedan 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 .