Conditions: if and switch

if, else and switch let a program choose what to do. C++17 added handy variations — an if with its own initialiser, and if constexpr for compile-time decisions — that keep code tidy.

if, else if, else

C++
#include <iostream>

int main() {
    for (int score : {95, 82, 67, 40}) {
        char grade;
        if (score >= 90) {
            grade = 'A';
        } else if (score >= 75) {
            grade = 'B';
        } else if (score >= 50) {
            grade = 'C';
        } else {
            grade = 'F';
        }
        std::cout << score << " -> " << grade << '\n';
    }
}
Output
95 -> A
82 -> B
67 -> C
40 -> F

Conditions are checked in order and only the first true branch runs. Always use braces, even for single statements — it prevents bugs when lines are added later.

if with an initialiser

C++17 lets you declare a variable inside the if, scoped to the whole if/else chain. It keeps temporary values out of the surrounding code:

C++
#include <iostream>
#include <map>
#include <string>

int main() {
    std::map<std::string, int> stock{{"apples", 30}, {"pears", 0}};
    for (std::string fruit : {"apples", "pears", "kiwis"}) {
        if (auto it = stock.find(fruit); it == stock.end()) {
            std::cout << fruit << ": not sold here\n";
        } else if (it->second == 0) {
            std::cout << fruit << ": sold out\n";
        } else {
            std::cout << fruit << ": " << it->second << " in stock\n";
        }
    }
}
Output
apples: 30 in stock
pears: sold out
kiwis: not sold here

std::map (lesson 21) maps keys to values; find returns an iterator (lesson 23) that's end() when the key is missing.

Logical conditions

C++
#include <iostream>

int main() {
    int hour = 14;
    bool weekend = false;
    if (hour >= 9 && hour < 17 && !weekend) {
        std::cout << "Office open\n";
    }
    int temperature = -3;
    if (temperature < 0 || temperature > 35) {
        std::cout << "Extreme temperature warning\n";
    }
}
Output
Office open
Extreme temperature warning

Remember that 9 <= hour < 17 doesn't mean what it looks like — write two comparisons joined with &&.

switch

switch compares one integer, character or enum value against constant cases:

C++
#include <iostream>

enum class Command { start, stop, pause, status };

void run(Command c) {
    switch (c) {
        case Command::start:  std::cout << "Starting\n"; break;
        case Command::stop:   std::cout << "Stopping\n"; break;
        case Command::pause:
        case Command::status:
            std::cout << "Not implemented yet\n";
            break;
    }
}

int main() {
    run(Command::start);
    run(Command::status);
}
Output
Starting
Not implemented yet

Without break, execution falls through into the next case — useful for grouping cases, a bug when forgotten. Mark deliberate fall-through after code with [[fallthrough]]; so compilers don't warn. When you switch on an enum class and handle every value without a default, compilers warn if a new value is added later and not handled.

C++
#include <iostream>

enum class Light { red, amber, green };

const char* action(Light l) {
    switch (l) {
        case Light::red:   return "stop";
        case Light::green: return "go";
    }
    return "?";
}

int main() {
    std::cout << action(Light::amber) << '\n';
}
Compiler warnings
main.cpp:6:13: warning: enumeration value 'amber' not handled in switch [-Wswitch]

switch with an initialiser

C++
#include <iostream>
#include <string>

int main() {
    std::string input = "q";
    switch (char c = input.empty() ? '?' : input[0]; c) {
        case 'q': std::cout << "quit\n"; break;
        case 'h': std::cout << "help\n"; break;
        default:  std::cout << "unknown: " << c << '\n'; break;
    }
}
Output
quit

if constexpr

if constexpr chooses a branch at compile time and discards the other. It's mainly for templates (lesson 39), where code must adapt to different types:

C++
#include <iostream>
#include <string>
#include <type_traits>

template <typename T>
void describe(const T& value) {
    if constexpr (std::is_integral_v<T>) {
        std::cout << value << " is an integer\n";
    } else if constexpr (std::is_floating_point_v<T>) {
        std::cout << value << " is a floating-point number\n";
    } else {
        std::cout << "\"" << value << "\" is something else\n";
    }
}

int main() {
    describe(42);
    describe(2.5);
    describe(std::string{"text"});
}
Output
42 is an integer
2.5 is a floating-point number
"text" is something else

Try it yourself

Classify a body-mass index using if/else if.

Try it yourself · main.cpp
Edit the code, copy it into main.cpp, then compile and run it with c++ -std=c++20 -Wall main.cpp -o main && ./main. How to set up a C++ compiler
Output
BMI 22.7244: healthy