C/C++ Arena

Step 1 of 7

std::optional

Many functions sometimes have no answer: searching for something that isn't there, parsing text that isn't a number. Old code signals that with a magic value like -1, 0 or nullptr, and every caller has to know (and remember) which value means "nothing". Worse, sometimes -1 is a perfectly valid answer.

std::optional<T> (from <optional>) makes "maybe" part of the type. It holds either a T or nothing, so the "nothing" case is visible right in the function's signature and hard to overlook.

#include <iostream>
#include <optional>
#include <string>
#include <vector>

std::optional<double> average(const std::vector<int>& v) {
    if (v.empty()) return std::nullopt;         // no data, no average
    double sum = 0;
    for (int x : v) sum += x;
    return sum / v.size();                      // a double converts to optional<double>
}

int main() {
    std::vector<int> full = {3, 4, 8};
    std::vector<int> empty;

    if (auto a = average(full)) {
        std::cout << "average " << *a << "\n";
    }
    auto b = average(empty);
    std::cout << "has value? " << b.has_value() << "\n";
    std::cout << "with default: " << b.value_or(0.0) << "\n";
}
average 5
has value? 0
with default: 0

How it works

Your task: parsing an int by hand

Walk the string character by character:

  1. Empty string: fail.
  2. If the first character is -, remember it and start from index 1. If that leaves nothing, fail (a lone -).
  3. Every remaining character must be '0' to '9'. Build the number with v = v * 10 + (c - '0').
  4. Apply the sign at the end.

Your turn: write std::optional<int> parse_int(const std::string& s) that returns the number for strings made only of digits (with an optional leading -), and std::nullopt otherwise (including the empty string and a lone -).

Next: std::variant and std::visit