Operator | Symbol | Form | Meaning |
---|---|---|---|
Conditional | ?: | c ? x : y | If conditional c is true then evaluate x , otherwise evaluate y |
The conditional operator (?:
) (also sometimes called the arithmetic if operator) is a ternary operator (an operator that takes 3 operands). Because it has historically been C++’s only ternary operator, it’s also sometimes referred to as “the ternary operator”.
The ?:
operator provides a shorthand method for doing a particular type of if-else statement.
Related content
We cover if-else statements in lesson 4.10 -- Introduction to if statements.
To recap, an if-else statement takes the following form:
if (condition) statement1; else statement2;
If condition
evaluates to true
, then statement1
is executed, otherwise statement2
is executed. The else
and statement2
are optional.
The ?:
operator takes the following form:
condition ? expression1 : expression2;
If condition
evaluates to true
, then expression1
is evaluated, otherwise expression2
is evaluated. The :
and expression2
are not optional.
Consider an if-else statement that looks like this:
if (x > y)
greater = x;
else
greater = y;
This can be rewritten as:
greater = ((x > y) ? x : y);
In such cases, the conditional operator can help compact code without losing readability.
The conditional operator evaluates as an expression
Because the operands of the conditional operator are expressions rather than statements, the conditional operator can be used in places where an expression is required.
For example, when initializing a variable:
#include <iostream>
int main()
{
constexpr bool inBigClassroom { false };
constexpr int classSize { inBigClassroom ? 30 : 20 };
std::cout << "The class size is: " << classSize << '\n';
return 0;
}
There’s no direct if-else replacement for this. You might think to try something like this:
#include <iostream>
int main()
{
constexpr bool inBigClassroom { false };
if (inBigClassroom)
constexpr int classSize { 30 };
else
constexpr int classSize { 20 };
std::cout << "The class size is: " << classSize;
return 0;
}
However, this won’t compile, and you’ll get an error message that classSize
isn’t defined. Much like how variables defined inside functions die at the end of the function, variables defined inside an if-statement or else-statement die at the end of the if-statement or else-statement. Thus, classSize
has already been destroyed by the time we try to print it.
If you want to use an if-else, you’d have to do something like this:
#include <iostream>
int getClassSize(bool inBigClassroom)
{
if (inBigClassroom)
return 30;
else
return 20;
}
int main()
{
const int classSize { getClassSize(false) };
std::cout << "The class size is: " << classSize;
return 0;
}
This one works because getClassSize(false)
is an expression, and the if-else logic is inside a function (where we can use statements). But this is a lot of extra code when we could just use the conditional operator instead.
Parenthesizing the conditional operator
Because C++ prioritizes the evaluation of most operators above the evaluation of the conditional operator, it’s quite easy to write expressions using the conditional operator that don’t evaluate as expected.
Related content
We cover the way that C++ prioritizes the evaluation of operators in future lesson 6.1 -- Operator precedence and associativity.
For example:
#include <iostream>
int main()
{
int x { 2 };
int y { 1 };
int z { 10 - x > y ? x : y };
std::cout << z;
return 0;
}
You might expect this to evaluate as 10 - (x > y ? x : y)
(which would evaluate to 8
) but it actually evaluates as (10 - x) > y ? x : y
(which evaluates to 2
).
For this reason, the conditional operator should be parenthesized as follows:
- Parenthesize the entire conditional operator when used in a compound expression (an expression with other operators).
- For readability, parenthesize the condition if it contains any operators (other than the function call operator).
The operands of the conditional operator do not need to be parenthesized.
Let’s take a look at some statements containing the conditional operator and how they should be parenthesized:
return isStunned ? 0 : movesLeft; // not used in compound expression, condition contains no operators
int z { (x > y) ? x : y }; // not used in compound expression, condition contains operators
std::cout << (isAfternoon() ? "PM" : "AM"); // used in compound expression, condition contains no operators (function call operator excluded)
std::cout << ((x > y) ? x : y); // used in compound expression, condition contains operators
Best practice
Parenthesize the entire conditional operator when used in a compound expression.
For readability, parenthesize the condition if it contains any operators (other than the function call operator).
The type of the expressions must match or be convertible
To properly comply with C++’s type checking, either the type of both expressions in a conditional statement must match, or the second expression must be convertible to the type of the first expression.
So while you might expect to be able to do something like this:
#include <iostream>
int main()
{
constexpr int x{ 5 };
std::cout << (x != 5 ? x : "x is 5"); // won't compile
return 0;
}
The above example won’t compile. One of the expressions is an integer, and the other is a string literal. The compiler will try to find a way to convert the string literal to an integer, but since it doesn’t know how, it will give an error. In such cases, you’ll have to use an if-else.
So when should you use the conditional operator?
The conditional operator is most useful when doing one of the following:
- Initializing an object with one of two values.
- Assigning one of two values to an object.
- Passing one of two values to a function.
- Returning one of two values from a function.
- Printing one of two values.
Complicated expressions should generally avoid use of the conditional operator, as they tend to be error prone and hard to read.
Best practice
Prefer to avoid the conditional operator in complicated expressions.