Operators and Expressions

The Conditional Operator

The conditional operator is a concise way of picking one of two values, based on whether a condition is true or false. It's indicated by a question mark and a colon, and is also called the ternary operator since it has three operands:

// Choose between the two expressions using this condition
condition ? expression_if_true : expression_if_false

The expression for the condition is evaluated first. If it’s true, then the overall value of the operator expression is the value of the expression after the question mark. Otherwise, the value of the expression after the colon is used instead.

Only one of the two expressions that appear after the question mark and colon, respectively, will ever be evaluated. Both will not be evaluated.

To start off, the condition at the beginning of a conditional expression is tested.

Then, if the result of that condition test is true, the entire conditional expression becomes the value from after the question mark. If the condition fails and is false, then the entire expression becomes the value after the colon.

int score{75};
int grade{(score >= 60) ? 1 : 0};

Since the entire conditional operator is an expression itself and not a statement, it can be used where any expression value is expected. For example, it can be used as a parameter to a function, be put in an assignment as the value to the variable, or used on the right side of a function call.

Parentheses are optional when writing the condition itself, but they can make it easier to distinguish it from the surrounding C++ code.

The results of the two expressions after the question mark must be able to be converted to a single type.

The C++ compiler will determine the appropriate type, and will then yield a value of that type as the result of the entire conditional operator expression.

int whole{10};
double scale{2.5};
double result{(whole > 0) ? scale : 0.0};

If you are choosing between an integer value and a floating point value, typically the value of the integer will be converted into a floating point value, according to standard C++ data conversion rules.

If the results of the two branches can be converted to a common type, the program will compile. If not, a compilation error will occur.

It's also possible to nest conditional operators within each other, like this:

// Parenthesize the nested conditional to make its grouping clear
int value{(x > 0) ? (y > 0) ? 1 : -1 : 0};

The conditional operator groups itself to the right, which makes the expression equivalent to:

int value{(x > 0) ? ((y > 0) ? 1 : -1) : 0};

However, if you use too many nested conditional operators, it gets increasingly harder to track where each part of the expression ends.

When using a conditional operator expression, it is important to understand that one of the two expressions is never actually evaluated.

If the condition evaluates to true, then only the expression after the question mark is evaluated.

If it evaluates to false, then only the expression after the colon is evaluated.

int divisor{0};
// Only evaluate the division when the divisor is nonzero
int safe{(divisor != 0) ? (100 / divisor) : -1};

This feature of the conditional operator helps avoid any unnecessary computations, and, more importantly, helps prevent an illegal operation from being attempted when it simply isn't suitable to run. Also, if the operation which was not evaluated did have side effects, those side effects are not executed either.

The conditional operator has relatively low precedence when compared to other C++ operators such as arithmetic operators and comparisons.

Assignment operators have lower precedence than the conditional operator and are typically evaluated after the conditional operator.

This allows you to have the result of an arithmetic expression be compared before one or the other expression contained within the conditional operator is evaluated.

int result{x + y > 10 ? 1 : 0};

This is interpreted as:

int result{(x + y > 10) ? 1 : 0};

Again, parentheses should always be used to make sure the groupings are done as desired.

A conditional operator can convert any result of a comparison into either a 0 or a 1 integer.

It can be used as a simplified if statement that selects which one of two variables to put into another variable, based on which comparison is true.

It can also choose between two differing operations to make sure one that would be an error doesn't even get run.

A nested conditional operator may yield any of three results.

#include <iostream>

int main()
{
    int score{82};
    int pass{(score >= 60) ? 1 : 0};
    std::cout << "Pass flag: " << pass << '\n';

    int x{5};
    int y{12};
    int larger{(x > y) ? x : y};
    std::cout << "Larger value: " << larger << '\n';

    int temperature{3};
    std::cout << "Feeling: " << ((temperature > 20) ? "warm" : "cold") << '\n';

    int divisor{0};
    // Integer division discards the fractional part
    int quotient{(divisor != 0) ? (100 / divisor) : -1};
    std::cout << "Safe quotient: " << quotient << '\n';

    int a{7};
    int b{7};
    int comparison{(a < b) ? -1 : (a > b) ? 1 : 0};
    std::cout << "Comparison result: " << comparison << '\n';
}
Exercise: The Conditional OperatorStarter code, hints and solutionOpenClose
Guided practiceBeginner · 10–15 min

Practice: The Conditional Operator

Work through the mission, reveal hints only when needed, and compare your result with the model solution.

Your challenge

Change score to 59. Predict the selected branch of the conditional operator and the resulting pass flag.

Mission checklist

  1. Run the starter as a baseline, then predict the change requested in Your challenge.
  2. Make that change in your editor; use the lesson-specific hints if you need help.
  3. Compile and run your answer, then compare with the worked solution and explain the result.

Starter program

This is the working baseline, not the completed answer. Compile as C++20, then make the change described above.

#include <iostream>

int main()
{
    int score{82};
    int pass{(score >= 60) ? 1 : 0};
    std::cout << "Pass flag: " << pass << '\n';

    int x{5};
    int y{12};
    int larger{(x > y) ? x : y};
    std::cout << "Larger value: " << larger << '\n';

    int temperature{3};
    std::cout << "Feeling: " << ((temperature > 20) ? "warm" : "cold") << '\n';

    int divisor{0};
    // Integer division discards the fractional part
    int quotient{(divisor != 0) ? (100 / divisor) : -1};
    std::cout << "Safe quotient: " << quotient << '\n';

    int a{7};
    int b{7};
    int comparison{(a < b) ? -1 : (a > b) ? 1 : 0};
    std::cout << "Comparison result: " << comparison << '\n';
}

Hints

Hint 1

Read condition ? first : second as selecting one of two values. With score >= 60, the true branch supplies 1 and the false branch supplies 0.

Hint 2

Try score just below 60 to switch the pass flag. In the quotient expression, only the selected branch runs, so a zero divisor selects -1 without performing division.

Worked solution

score is changed from 82 to 59. score >= 60 is now false, so the conditional operator selects 0 for pass. Only the selected branch supplies the value.

#include <iostream>

int main()
{
    int score{59};
    int pass{(score >= 60) ? 1 : 0};
    std::cout << "Pass flag: " << pass << '\n';

    int x{5};
    int y{12};
    int larger{(x > y) ? x : y};
    std::cout << "Larger value: " << larger << '\n';

    int temperature{3};
    std::cout << "Feeling: " << ((temperature > 20) ? "warm" : "cold") << '\n';

    int divisor{0};
    // Integer division discards the fractional part
    int quotient{(divisor != 0) ? (100 / divisor) : -1};
    std::cout << "Safe quotient: " << quotient << '\n';

    int a{7};
    int b{7};
    int comparison{(a < b) ? -1 : (a > b) ? 1 : 0};
    std::cout << "Comparison result: " << comparison << '\n';
}

Example output

Pass flag: 0
Larger value: 12
Feeling: cold
Safe quotient: -1
Comparison result: 0

0 comments

No comments yet. Be the first.

Add a comment

About CppLearn

CppLearn is an interactive, free reference for modern C++. In each lesson, you'll find out how the language works, rather than just lines of code that you can copy and paste. We cover concepts starting from beginner lessons on fundamentals and proceed to templates, move semantics, smart pointers, and areas that usually trap or scare C++ learners.