C/C++ Arena

Step 4 of 8

constexpr

Templates run the type machinery at compile time. constexpr lets ordinary calculations run at compile time too. A constexpr function can be evaluated by the compiler whenever its arguments are compile-time constants, and the result is baked into the program as a number.

#include <array>
#include <iostream>

constexpr int factorial(int n) {
    int result = 1;
    for (int i = 2; i <= n; i++) result *= i;
    return result;
}

constexpr int cube(int x) { return x * x * x; }

static_assert(factorial(5) == 120);           // checked while compiling
static_assert(cube(3) == 27, "cube is broken");

int main() {
    std::array<int, cube(2)> slots{};         // size 8, known at compile time
    std::cout << slots.size() << "\n";

    constexpr int f6 = factorial(6);          // computed by the compiler
    std::cout << f6 << "\n";

    int n = 4;                                // a run-time value...
    std::cout << factorial(n) << "\n";        // ...so this call runs normally
}
8
720
24

How it works

Your task: power

Multiply result by base, exp times, starting from result = 1. Mark the function constexpr; the tests use static_assert, so without it the tests won't even compile. Use long long for the result so big powers fit.

Your task

Write constexpr long long power(long long base, int exp). The tests include static_asserts, so if your function can't run at compile time, it won't even compile.

Challenge 2

Write constexpr bool is_prime(int n) (false below 2) and constexpr int count_primes_below(int n). The tests use static_assert, so both must work at compile time.

Challenge 3

Write template <std::size_t N> constexpr std::array<int, N> first_squares() returning {0, 1, 4, 9, ...}, the first N squares. It must work at compile time.

Previous: Class templates Next: if constexpr