Operator ternary kondisi ? nilaiA : nilaiB adalah satu-satunya operator C++ yang bekerja dengan tiga operand. Ia membaca sebuah kondisi, lalu menghasilkan nilai cabang pertama bila kondisinya true atau cabang kedua bila false — hanya satu cabang yang dievaluasi, seperti perilaku short-circuit pada operator logika. Kekuatan utamanya: ternary adalah ekspresi, sehingga hasilnya bisa langsung disimpan ke variabel, dikirim ke std::cout, atau dipakai di tengah ekspresi lain. Pada Chapter ini kita menguji bentuk dasarnya, menyelidiki aturan tipe kedua cabang, dan membahas kapan ternary bertingkat (nested) layak atau tidak layak ditulis.

Bentuk Dasar: Kondisi, Lalu Dua Cabang #

Pola umumnya: hasil = kondisi ? nilaiJikaBenar : nilaiJikaSalah;. Karena menghasilkan nilai, satu baris ternary menggantikan pola “isi variabel menurut kondisi” yang baru bisa kita tulis dengan pernyataan kondisi setelah Section Control Flow — dan dalam banyak kasus satu baris ternary tetap lebih ringkas.

cpp
#include <iostream>
#include <string>

int main() {
    int nilai = 78;

    // Ternary adalah ekspresi: hasilnya bisa langsung disimpan
    std::string status = (nilai >= 75) ? "lulus" : "remedial";
    std::cout << "Nilai " << nilai << " -> " << status << "\n\n";

    // Bisa berdiri di tengah ekspresi lain
    int suhu = 30;
    std::cout << "Kipas: " << (suhu > 28 ? "menyala" : "mati") << "\n\n";

    // Tipe kedua cabang disamakan: 1 dan 0.5 menjadi double
    auto poin = (nilai > 80) ? 1 : 0.5;
    std::cout << "poin = " << poin << "\n\n";

    // Nested ternary: sah, tetapi cepat sulit dibaca
    int jam = 14;
    std::string sapaan = (jam < 11) ? "Selamat pagi"
                       : (jam < 15) ? "Selamat siang"
                       : "Selamat malam";
    std::cout << "Jam " << jam << " -> " << sapaan << "\n";

    return 0;
}

Output yang Dihasilkan:

text
Nilai 78 -> lulus

Kipas: menyala

poin = 0.5

Jam 14 -> Selamat siang

Mari kita bedah baris demi baris:

  1. Baris 8 (std::string status = ...): kondisi nilai >= 75 benar (78 >= 75), sehingga cabang "lulus" yang dihasilkan dan disimpan ke status. Kurung di sekitar kondisi tidak wajib, tetapi membuat batas kondisi terbaca jelas.
  2. Baris 12-13: ternary berdiri di tengah rantai <<. Karena 30 > 28, yang dikirim ke std::cout adalah "menyala". Perhatikan kurung keseluruhan diperlukan agar << tidak memotong ekspresi ternary.
  3. Baris 16-17: auto menebak tipe hasil ternary. Kedua cabang adalah 1 (int) dan 0.5 (double); compiler menyatukannya menjadi double, sehingga poin bertipe double. Karena 78 > 80 salah, nilai 0.5 yang muncul.
  4. Baris 20-23 (nested ternary): kondisi pertama jam < 11 salah, lalu cabang kedua menguji jam < 15 yang benar, sehingga "Selamat siang" yang dipilih. Cabang ketiga "Selamat malam" tidak dievaluasi.

Hanya Satu Cabang yang Dievaluasi #

Seperti && dan ||, operator ternary mengevaluasi kondisi lebih dulu, lalu hanya menjalankan salah satu cabang. Sifat ini penting bila cabang mengandung operasi dengan efek samping, misalnya penambahan penghitung atau penulisan ke stream: cabang yang tidak dipilih tidak pernah berjalan. Anda bisa menghitung kepastian urutannya, dan itulah alasan ternary aman untuk ekspresi yang mahal di salah satu cabangnya.

Tipe Kedua Cabang Harus Bisa Disatukan #

Compiler menentukan satu tipe hasil dari kedua cabang. Bila tipenya berbeda tetapi bisa dikonversi — seperti int dan double — nilai cabang yang terpilih dikonversi ke tipe hasil tersebut; itulah yang terjadi pada poin di atas. Bila kedua cabang bertipe yang sama sekali tidak terhubung, program gagal dikompilasi, seperti pada contoh berikut:

cpp Contoh: cabang bertipe tak terhubung
auto label = true ? "ya" : 1;   // const char* vs int

Pesan compiler untuk potongan tersebut jelas menyebut penyebabnya:

text
error: operands to '?:' have different types 'const char*' and 'int'

Aturan ini wajar diingat karena hasil ternary dipakai sebagai satu nilai — compiler harus tahu persis tipe nilainya. Berbeda dengan pola pernyataan kondisi (kita pelajari di Section Control Flow) yang dua cabangnya boleh melakukan aksi dengan tipe apa pun.

Ternary Bertingkat: Bisa, Tetapi Hemat #

Ternary bisa bersarang — cabangnya berupa ternary lain, seperti sapaan pada program di atas. Untuk dua-tiga pilihan yang membentuk tangga rentang (pagi/siang/malam), pola bertingkat yang ditulis rapi masih terbaca. Namun di titik itu kegunaannya berhenti: menumpuk lebih dari satu tingkat membuat pembaca harus menyusuri ? dan : secara manual, dan mudah salah menaruh kurung.

Kaidah yang sehat: nested ternary hanya bila struktur pilihannya benar-benar sederhana, setiap cabang pendek, dan penulisannya dilipat rapi seperti contoh kita. Untuk logika pilihan yang lebih kompleks, pernyataan kondisi (Chapter if-else dan switch pada Section Control Flow) jauh lebih mudah dipelihara.

Ternary memilih nilai dari dua kandidat. Chapter berikutnya membahas operator yang bukan memilih nilai, melainkan menentukan nama mana yang dimaksud saat ada beberapa entitas bernama sama: operator scope resolution ::.