Control Flow

Control Flow

Branching, loops, scope, and common flow-control patterns.

Control Flow

Conditional statements

if (score >= 90) {
    grade = 'A';
} else if (score >= 80) {
    grade = 'B';
} else {
    grade = 'C';
}

switch

switch (token) {
case '+':
    handle_add();
    break;
case '-':
    handle_subtract();
    break;
default:
    handle_unknown();
    break;
}

Loops

for (int i = 0; i < 10; ++i) {
    total += i;
}

while (!done) {
    poll();
}

do {
    read_again();
} while (retry);

Range-based for

for (const auto& item : items) {
    std::cout << item << '\n';
}

Loop control

if with initializer

if (auto it = map.find(key); it != map.end()) {
    use(it->second);
}

switch with enums

enum class State { idle, running, done };

Prefer enum class to avoid accidental implicit conversions.

Best-practice reminders

Quick decision guide

constexpr if

template <typename T>
void print_kind(const T& value) {
    if constexpr (std::is_integral_v<T>) {
        std::cout << "integral: " << value << '\n';
    } else {
        std::cout << "other: " << value << '\n';
    }
}

Use if constexpr in templates when a branch should disappear entirely for some types.

Modern switch habits

switch (state) {
case State::idle:
    start();
    break;
case State::running:
    [[fallthrough]];
case State::paused:
    resume();
    break;
}

Loop pitfalls worth remembering

Guard-clause pattern

bool handle_request(const Request& request) {
    if (!request.authenticated()) {
        return false;
    }
    if (!request.has_payload()) {
        return false;
    }

    process(request.payload());
    return true;
}

This is usually easier to scan than pushing the main logic into another indentation level.

Small state-machine pattern

switch (state) {
case State::idle:
    start();
    break;
case State::running:
    step();
    break;
case State::done:
    cleanup();
    break;
}

When a switch starts accumulating too much work per case, move each branch into a helper so the state transition stays obvious.

Example in practice

enum class Command { start, stop, reload };

void handle(Command command) {
    switch (command) {
    case Command::start:
        start();
        return;
    case Command::stop:
        stop();
        return;
    case Command::reload:
        reload();
        return;
    }
}

Try this variation

Refactor the example into a named helper with a single responsibility. If the logic gets easier to test, the design probably improved.

bool is_even(int value) {
    return value % 2 == 0;
}

int main() {
    return is_even(4) ? 0 : 1;
}