Language[lang]
C++ ternary operator (?:): syntax and examples
- Section
- Language [lang]
- Standard
- C++17
- Compilers
- MSVC 19.44, Clang 19.1 (MSVC STL), GCC 16.2, Clang 23.1 (libc++)
- Published
- Length
- 7 min read
In this answer7 clauses
- 1Ternary operator vs if-else: what is the difference?
- 2When should you use the ternary operator?
- 3What type does the ternary operator return (numbers and strings)?
- 4Can you nest ternary operators?
- 5Why does
cout << x ? a : bprint the wrong thing? - 6Does the ternary operator evaluate both sides?
- 7Ternary or if-else: which one?
Abstract
The C++ ternary operator, condition ? a : b, is an expression that gives a when the condition is true and b when it is false, so it can initialize a variable, a const one included, or sit in a return or a function argument. Both branches must agree on a type, only the chosen one is evaluated, and inside a std::cout chain it needs parentheses.

The C++ ternary operator, condition ? a : b, is an expression that gives a when the condition is true and b when it is false. It is a compact if-else that produces a value, so it can sit where a statement cannot: in an initializer, a return or a function argument. Its formal name is the conditional operator.
A test score, in a whole program:
#include <iostream>
#include <string>
int main() {
int score = 72;
std::string result = score >= 60 ? "pass" : "fail";
std::cout << "Score " << score << ": " << result << '\n';
}— end example]
It printed:
Score 72: pass— end example]
Read the line as “if the score is at least 60, then pass, otherwise fail”. score >= 60 is the condition, anything that converts to bool; 72 meets it, so result holds “pass”. The operator needs no header and has been in C++ since C++98. The samples are C++17 (Since When’s C++17 table lists the first GCC, Clang and MSVC releases for its features), built with MSVC 19.44, Clang 19.1 (MSVC STL), GCC 16.2 and Clang 23.1 (libc++), and all four printed the same.
Ternary operator vs if-else: what is the difference?
An if-else is a statement, a step the program carries out: it does one thing or another. The ternary operator is an expression, a piece of code that has a value: it is one value or another. The same choice, both ways:
std::string by_if;
if (score >= 60) {
by_if = "pass";
} else {
by_if = "fail";
}
std::string by_ternary = score >= 60 ? "pass" : "fail";
std::cout << by_if << ' ' << by_ternary << '\n'; // pass pass
int age = 9;
const int fee = age < 12 ? 5 : 10; // a const set in one step
std::cout << "Fee: " << fee << '\n'; // Fee: 5— end example]
The if-else declares by_if empty and sets it in one of two places; the ternary sets by_ternary as it is declared. That matters for the entry fee: fee is const, a variable that cannot change once set, so an if-else could not assign it afterwards, while the ternary gives it its value in one step.
| Question | if-else | Ternary operator |
|---|---|---|
| What it is | a statement | an expression |
| Gives a value | no | yes |
| Each branch holds | any statements | one expression |

When should you use the ternary operator?
Use it for a short choice between two values: to initialize a variable, in a return, as a function argument, or to pick a singular or plural word. Each of those is a place that needs a value:
int larger(int a, int b) {
return a > b ? a : b;
}
void announce(const char* result) {
std::cout << "Result: " << result << '\n';
}
int main() {
std::cout << larger(72, 85) << '\n'; // 85
int score = 72;
announce(score >= 60 ? "pass" : "fail"); // Result: pass
int count = 1;
std::cout << count << (count == 1 ? " item" : " items") << '\n';
count = 3;
std::cout << count << (count == 1 ? " item" : " items") << '\n';
}— end example]
The last two lines printed 1 item and 3 items. Write an if-else instead when the two sides do different things rather than give different values, or when either side is long enough that the ? and the : get lost in it.
What type does the ternary operator return (numbers and strings)?
The whole expression has one type, worked out from both branches: an int and a double give a double, and a string literal (text in double quotes) with a std::string gives a std::string (the conditional operator on cppreference). Below, decltype names the type of an expression and std::is_same_v asks whether two types are the same:
std::cout << std::boolalpha;
bool member = true;
auto price = member ? 8 : 9.5; // int and double: double
std::cout << std::is_same_v<decltype(price), double> << '\n';
std::cout << price << '\n'; // 8, held as 8.0
bool ok = true;
std::string label = ok ? "yes" : std::string("no");
std::cout << label << '\n'; // yes
// the type of each whole expression, checked by the compiler
using Mixed = decltype(ok ? "yes" : std::string("no"));
using Words = decltype(ok ? "yes" : "no");
std::cout << std::is_same_v<Mixed, std::string> << '\n';
std::cout << std::is_same_v<Words, const char*> << '\n';— end example]
Every check printed true. price is a double though member picked the 8, and std::cout printed it as 8. Two string literals, ok ? "yes" : "no", give a pointer to characters (const char*), not a std::string. With auto, the first example’s result would have been a const char*. To get a std::string from a choice between two pieces of text, declare the variable as std::string, as that example does, or make one branch a std::string, as label does.
Branches with no common type do not compile:
auto value = ok ? 1 : "none"; // error: a number or text?— end example]
GCC said:
error: operands to '?:' have different types 'int' and 'const char*'— end example]
All four refused it. One branch may instead be a throw, which has no value; the expression then takes the other branch’s type (how try, catch and throw work).
Can you nest ternary operators?
Yes. A nested ternary operator has another ternary as a branch, and laid out with one condition per line it reads as a chain. A letter grade from a score, beside the same chain as an if-else:
char grade_ternary(int score) {
return score >= 90 ? 'A'
: score >= 80 ? 'B'
: score >= 70 ? 'C'
: score >= 60 ? 'D'
: 'F';
}
char grade_if(int score) {
if (score >= 90) {
return 'A';
} else if (score >= 80) {
return 'B';
} else if (score >= 70) {
return 'C';
} else if (score >= 60) {
return 'D';
} else {
return 'F';
}
}— end example]
For 95, 72 and 41 both returned A, C and F. The operator groups from the right, so the chain is read as score >= 90 ? 'A' : (score >= 80 ? 'B' : ...) with no parentheses written: each line that starts with : is the else of the line above it. Past three outcomes, prefer the if-else chain: it is as easy to scan, and any branch can grow into more than a value.
Why does cout << x ? a : b print the wrong thing?
Because << binds tighter than ?:, std:: sends passed to the stream and throws the chosen word away. Put the ternary in parentheses:
bool passed = true;
std::cout << passed ? "pass" : "fail"; // prints 1
std::cout << '\n';
std::cout << (passed ? "pass" : "fail") << '\n'; // prints pass— end example]
It printed:
1
pass— end example]
The first line is read as (std:: (the operator precedence table puts << far above ?:), so the bool is printed as 1, the stream itself (which converts to bool) becomes the condition, and the chosen word goes nowhere. Do not count on a warning: Clang says operator '?:' has lower precedence than '<<'; '<<' will be evaluated first even with no warning flags, GCC with -Wall only that the second and third operands, the two values, have no effect, and MSVC at /W4 says nothing.
With a comparison as the condition, the same slip does not compile:
std::cout << score >= 60 ? "pass" : "fail"; // error— end example]
<< runs first again, so >= is asked to compare the stream with 60. GCC said no match for 'operator>=', and all four refused it. The same parentheses fix it, and they are why the item lines earlier wrap their choice in them. An assignment needs none: a = b ? c : d is read as a = (b ? c : d).
Does the ternary operator evaluate both sides?
No. Only the chosen branch runs ([expr.cond]: “only one of the second and third expressions is evaluated”), which is what makes count != 0 ? total / count : 0 safe:
int pass_bonus() {
std::cout << "pass_bonus called\n";
return 5;
}
int fail_bonus() {
std::cout << "fail_bonus called\n";
return 0;
}
// ...
int score = 72;
int bonus = score >= 60 ? pass_bonus() : fail_bonus();
std::cout << "bonus " << bonus << '\n';
int total = 0;
int count = 0;
int average = count != 0 ? total / count : 0; // no division
std::cout << "average " << average << '\n';— end example]
It printed pass_bonus called, bonus 5 and average 0: fail_bonus never ran, and with count at 0 the division was never evaluated.
Ternary or if-else: which one?
Pick by what the code has to produce:
| You need | Write |
|---|---|
| One value from a yes-or-no question | a ternary |
A const set from a condition |
a ternary |
| Two different actions | an if-else |
| More than three outcomes | an if-else chain or a switch |
A choice inside a std::cout << chain |
a ternary in parentheses |
C++ does not let you overload ?:; how to overload operators in C++ covers the ones you can. The Language section has the other answers on the core language.
Questions
What is the ternary operator called in C++?
Its formal name is the conditional operator. “Ternary” means it takes three operands, the values an operator works on: the condition and the two branches. It is the only C++ operator that always takes exactly three.
Can a ternary operator have multiple statements?
No. Each branch is a single expression, not a block, so it cannot hold statements such as a declaration, a loop or a return. To return one of two values, put the ternary after the return, as in return a > b ? a : b;. When a branch has to do several things, write an if-else.
Can a ternary operator have multiple conditions?
Yes. The condition is any expression that converts to bool, so it can join tests with && and ||, as in const int fee = age < 12 || age >= 65 ? 5 : 10;, which gave 5 for an age of 70. Both operators bind tighter than ?:, so the condition needs no parentheses.
Can you use a ternary operator without else?
No. The grammar requires both branches, the one after the ? and the one after the :, so there is no form without the second. To do something only when a condition holds, write an if with no else.
Can you assign to the result of a ternary operator?
Yes, when both branches are variables of the same type: the result is then one of the two variables, not a copy of its value. With a = 72 and b = 45, (a < b ? a : b) = 0; set b to 0, and the program printed 72 0.
Can you throw inside a ternary operator?
Yes. One branch may be a throw expression, as in int age = text_ok ? 30 : throw std::runtime_error(“bad age”), and the whole expression then has the type of the other branch, here int. When text_ok is false, the exception is thrown and no value is produced; a handler such as catch (const std::runtime_error& e) receives it.
Sources
- Other operators: the conditional operatorcppreference.com
- C++ operator precedencecppreference.com
- [expr.cond] Conditional operatorC++ standard working draft