C++23 adalah standar yang terbit paling baru (disahkan ISO 2024), dan pilihannya sangat pragmatis: fitur-fiturnya ditujukan untuk kode sehari-hari, bukan untuk paradigma baru. std::print mengakhiri era std::cout << ... << ... untuk keluaran berformat; std::expected memberi cara standar mengembalikan nilai atau galat tanpa exception; deducing this menyederhanakan duplikasi method const/non-const; subscript multidimensi membuat m[i, j] legal; std::generator membuat coroutine layak pakai tanpa menulis promise type sendiri; dan static operator() mempercepat pemanggilan fungsi objek. Standar ini adalah target penuh toolchain kita (g++ 14.2), sehingga semua contoh di chapter ini benar-benar kita jalankan.
Program Demo Fitur C++23 #
// fitur-cpp23.cpp — C++23: print, expected, deducing this, generator, dan lainnya
// Kompilasi: g++ -std=c++23 -Wall -Wextra fitur-cpp23.cpp -o fitur23
#include <expected>
#include <generator>
#include <print>
#include <ranges>
#include <string>
// deducing this (C++23): parameter objek eksplisit, satu versi untuk semua cv
struct Kotak {
int isi = 0;
void lihat(this const Kotak& self) {
std::print("isi = {}\n", self.isi);
}
void ubah(this Kotak& self, int nilaiBaru) {
self.isi = nilaiBaru;
}
};
// static operator() (C++23): call operator tanpa instance
struct Penjumlah {
static int operator()(int a, int b) { return a + b; }
};
// multidimensional subscript (C++23): operator[] dua indeks
struct Matriks2x2 {
int data[4] = {};
int& operator[](std::size_t baris, std::size_t kolom) {
return data[baris * 2 + kolom];
}
int operator[](std::size_t baris, std::size_t kolom) const {
return data[baris * 2 + kolom];
}
};
// std::generator (C++23): coroutine siap pakai untuk deret malas
std::generator<int> fibonacci() {
int a = 0, b = 1;
while (true) {
co_yield a;
int berikut = a + b;
a = b;
b = berikut;
}
}
// std::expected (C++23): hasil atau galat, tanpa exception
std::expected<int, std::string> bagi(int a, int b) {
if (b == 0) {
return std::unexpected(std::string("pembagi nol"));
}
return a / b;
}
int main() {
std::print("mulai program\n");
Kotak k{.isi = 7};
k.lihat();
k.ubah(9);
k.lihat();
Penjumlah tambah;
std::print("Penjumlah: {}\n", tambah(2, 3));
Matriks2x2 m;
m[0, 0] = 5;
m[1, 1] = 8;
std::print("m[0,0]={} m[1,1]={}\n", m[0, 0], m[1, 1]);
for (int f : fibonacci() | std::views::take(8)) { // generator + view
std::print("{} ", f);
}
std::print("\n");
std::print("10/4 = {}\n", bagi(10, 4).value_or(-1));
auto gagal = bagi(10, 0);
if (!gagal) {
std::print("gagal: {}\n", gagal.error());
}
int lanjutan = bagi(9, 3)
.and_then([](int v) -> std::expected<int, std::string> { return v * 100; })
.value_or(-1);
std::print("9/3 x100 = {}\n", lanjutan);
if consteval { // jalur compile time vs runtime
std::print("dihitung saat kompilasi\n");
} else {
std::print("dihitung saat runtime\n");
}
return 0;
}Output yang Dihasilkan:
mulai program
isi = 7
isi = 9
Penjumlah: 5
m[0,0]=5 m[1,1]=8
0 1 1 2 3 5 8 13
10/4 = 2
gagal: pembagi nol
9/3 x100 = 300
dihitung saat runtimeMari kita bedah:
- Baris 14-19 (deducing this): parameter pertama ditulis eksplisit —
this const Kotak& selfuntuk baca,this Kotak& selfuntuk ubah. compiler menyimpulkan tipethissesuai konteks pemanggil, sehingga satu template bisa melayani versi lvalue, rvalue, const, dan non-const tanpa duplikasi. - Baris 23-25 (static operator()):
Penjumlah::operator()statis — dipanggil lewat objektambah(2, 3)namun tidak menyentuh state, sehingga tidak perlu instance yang memuat data dan pemanggilannya lebih murah. - Baris 28-37 (multidimensional subscript):
m[0, 0]danm[1, 1]memanggiloperator[](baris, kolom)dengan dua argumen — sebelum C++23,operator[]hanya boleh satu parameter sehingga class matriks terpaksa pakaioperator(). - Baris 40-48 (std::generator): fungsi biasa yang berisi
co_yieldotomatis menjadi coroutine;fibonacci()bisa diiterasi seperti container dan bahkan dirangkai denganviews::take(8). Delapan angka pertama tercetak:0 1 1 2 3 5 8 13. - Baris 51-56 (std::expected): kembalian
expected<int, string>berisi nilai ATAU galat.std::unexpectedmembungkus galat;value_or(-1)membaca nilai dengan cadangan aman;error()membaca pesan galat. - Baris 84-87 (monadic and_then):
and_thenmerantai operasi hanya bila nilai sukses — pola ini menggantikan sarangif (ok)berlapis. - Baris 89-93 (if consteval): memeriksa “apakah dievaluasi saat kompilasi?”; program ini dijalankan saat runtime, jadi cabang
elseyang tercetak.
std::mdspan: Jendela Multidimensi #
Teman sekelas std::span, std::mdspan memberi view multidimensi (baris-kolom-tensor) ke data kontigu tanpa memiliki datanya — ideal untuk membungkus buffer matriks tanpa menyalin:
#include <mdspan>
int data[6] = {1, 2, 3, 4, 5, 6};
std::mdspan m(data, 2, 3); // view 2x3 ke array yang sama
std::println("{}", m[1, 2]); // elemen baris 1 kolom 2 -> 6
Pada toolchain course ini (g++ 14.2), header <mdspan> belum tersedia sehingga contoh di atas hanya ilustrasi — lihat tabel dukungan compiler di cppreference
. Konsepnya tetap penting: mdspan adalah span untuk dimensi lebih dari satu.
C++23 menutup banyak permintaan praktis dan, seperti C++14, sifatnya pemoles — tetapi pemoles yang mengubah kebiasaan: setelah terbiasa std::print dan std::expected, kembali ke std::cout dan exception terasa melelahkan. Chapter berikutnya melihat ke depan: apa saja isi C++26 dan bagaimana kita mengecek dukungan compiler untuk fitur yang belum stabil.
Rujukan resmi: cppreference — fitur C++23 , cppreference — std::expected , cppreference — std::generator .