C/C++ Arena

Step 9 of 9

Challenge: compile-time computation

constexpr functions can run during compilation when their inputs are constants. The result is baked into the program as a literal, and static_assert can check it before the program even exists. Lookup tables, hashes of fixed strings, unit conversions and configuration checks are often done this way in performance-critical code: the work costs nothing at run time.

Since C++20, constexpr functions may use loops, local variables, std::array and even std::vector (as long as it doesn't escape the function).

#include <array>
#include <cstddef>
#include <iostream>

template <std::size_t N>
constexpr std::array<long, N> squares() {
    std::array<long, N> out{};
    for (std::size_t i = 0; i < N; i++) out[i] = (long)(i * i);
    return out;
}

constexpr int digit_sum(unsigned n) {
    int s = 0;
    while (n > 0) { s += n % 10; n /= 10; }
    return s;
}

constexpr auto table = squares<6>();          // built by the compiler
static_assert(table[5] == 25);
static_assert(digit_sum(2024) == 8);

int main() {
    for (long x : table) std::cout << x << " ";
    std::cout << "\n" << digit_sum(999) << "\n";
}
0 1 4 9 16 25 
27

How it works

Your task

Your turn:

Both must work at compile time: the tests use them inside static_assert.

Previous: CRTP and static polymorphism