Тернарный оператор в C++: синтаксис ?: и примеры

Тернарный оператор ?: в C++ простыми словами: как записать условие в одну строку, какого типа будет результат, зачем нужны скобки и когда лучше оставить обычный if-else.

Содержание

Тернарный оператор ?: выбирает одно из двух значений по условию. Это короткая запись if ... else для случая, когда обе ветки дают значение: что присвоить, что вывести, что вернуть из функции.

Синтаксис

C++
условие ? значение_если_истина : значение_если_ложь

Сначала вычисляется условие. Если оно истинно, результатом становится выражение после знака ?, иначе — выражение после двоеточия. Вычисляется только одна из двух веток.

Оператор называют тернарным, потому что у него три операнда. В C++ он единственный такой, поэтому «тернарный оператор» и «условный оператор ?:» — одно и то же.

Первый пример

Найдём большее из двух чисел. Сначала через if ... else:

C++
int max;
if (a > b) {
    max = a;
} else {
    max = b;
}

То же самое с тернарным оператором:

C++
int max = a > b ? a : b;

Запись стала короче, а переменная получает значение сразу при объявлении.

Где он удобен

Инициализация константы

Константу нельзя сначала объявить, а потом присвоить ей значение в if. Тернарный оператор решает задачу в одну строку:

C++
const int limit = isTest ? 10 : 1000;

Вывод на экран

C++
std::cout << "Число " << (n % 2 == 0 ? "чётное" : "нечётное") << '\n';

Возврат из функции

C++
int absolute(int x) {
    return x < 0 ? -x : x;
}

Аргумент функции

C++
printPrice(price, hasDiscount ? 0.9 : 1.0);

Во всех этих местах нужен результат-значение. Обычный if значения не даёт, поэтому без тернарного оператора пришлось бы заводить лишнюю переменную.

Скобки при выводе

У оператора ?: очень низкий приоритет — ниже, чем у сравнений, арифметики и оператора вывода <<. Поэтому в std::cout тернарное выражение нужно брать в скобки.

C++
std::cout << a > b ? a : b;      // ошибка компиляции
std::cout << (a > b ? a : b);    // правильно

Без скобок компилятор читает строку как (std::cout << a) > b ? a : b: сначала выводит a, а потом пытается сравнить поток вывода с числом. Такого сравнения не существует, и программа не собирается.

Какого типа результат

У тернарного выражения один тип, и он должен подходить обеим веткам. Если ветки разного типа, компилятор приводит их к общему.

C++
auto value = flag ? 1 : 2.5;   // тип double: единица станет 1.0

Здесь int и double приводятся к double, поэтому при flag == true переменная получит 1.0, а не 1.

Если общего типа нет, программа не скомпилируется:

C++
auto answer = flag ? 1 : "один";   // ошибка: int и строка несовместимы

Вложенные тернарные операторы

Тернарные операторы можно вкладывать, чтобы выбрать из трёх и более вариантов:

C++
std::string grade = score >= 90 ? "отлично"
                  : score >= 70 ? "хорошо"
                  : score >= 50 ? "удовлетворительно"
                  :               "неудовлетворительно";

Запись читается сверху вниз, как таблица: первое выполненное условие определяет ответ. В таком виде вложенность ещё понятна. Если же записать всё в одну строку или вложить оператор в ветку «истина», код превращается в головоломку:

C++
int result = a > b ? a > c ? a : c : b > c ? b : c;   // так писать не стоит

В этом случае лучше вернуться к if ... else if или вынести выбор в отдельную функцию.

Тернарный оператор или if-else

СитуацияЧто выбрать
Нужно выбрать одно из двух значенийтернарный оператор
Инициализируется const или ссылкатернарный оператор
В ветках выполняются действия: вывод, вызовы, несколько строкif ... else
Вариантов больше трёхif ... else if или switch
Условие и ветки не помещаются в одну строкуif ... else

Правило простое: тернарный оператор отвечает на вопрос «какое значение?», а if — на вопрос «что сделать?».

Что ещё полезно знать

Вычисляется только одна ветка. В выражении ptr != nullptr ? ptr->size : 0 обращение к ptr->size не произойдёт, если указатель нулевой.

Результату можно присваивать. Если обе ветки — переменные одного типа, тернарное выражение обозначает саму переменную, а не её копию:

C++
(a > b ? a : b) = 0;   // обнулит большую из двух переменных

В ветке может стоять throw. Так удобно проверять аргументы:

C++
int size = n > 0 ? n : throw std::invalid_argument("n должно быть положительным");

Частые ошибки

  • Нет скобок в std::cout. Из-за низкого приоритета выражение разбирается не так, как задумано.
  • Ветки разного типа. Результат неожиданно становится double, или код не компилируется.
  • Действия вместо значений. Запись x > 0 ? print(x) : print(-x); работает, но if ... else здесь понятнее.
  • Глубокая вложенность. Три условия в одной строке никто не прочитает с первого раза, включая автора через месяц.
  • Путаница с оператором ? из других языков. В C++ нет оператора ?? и сокращённой записи a ?: b — второй вариант существует только как расширение некоторых компиляторов.

Коротко

  • условие ? a : b даёт a, если условие истинно, и b, если ложно.
  • Это выражение со значением, поэтому оно подходит для инициализации, вывода и return.
  • Внутри других выражений берите его в скобки.
  • Обе ветки должны приводиться к одному типу.
  • Для действий и длинных условий используйте if ... else.

Остальные условные конструкции — if, else if и switch — разобраны в уроке Условные конструкции в C++. Отдельно про выбор из многих вариантов читайте в статье Оператор switch в C++.

Использованная литература

  1. Conditional operator — cppreference.com [Электронный ресурс]. — URL: https://en.cppreference.com/w/cpp/language/operator_other#Conditional_operator (дата обращения: 08.10.2026).
  2. ISO/IEC 14882:2024 — Язык программирования C++ [Электронный ресурс]. — URL: https://www.iso.org/standard/83626.html (дата обращения: 08.10.2026).