C/C++ Arena

Step 6 of 8

Values as template parameters

Template parameters don't have to be types. A non-type template parameter is a compile-time value, most often a size:

#include <cstddef>
#include <iostream>

template <typename T, std::size_t N>
class History {
public:
    void record(const T& v) {
        items_[next_ % N] = v;          // overwrite the oldest once full
        next_++;
    }
    std::size_t stored() const { return next_ < N ? next_ : N; }
    static constexpr std::size_t capacity() { return N; }

private:
    T items_[N]{};
    std::size_t next_ = 0;
};

int main() {
    History<int, 3> h;
    for (int i = 1; i <= 5; i++) h.record(i * 10);
    std::cout << h.stored() << " of " << h.capacity() << "\n";
    std::cout << History<char, 16>::capacity() << "\n";
    std::cout << "bigger N, bigger object: " << (sizeof(History<int, 100>) > sizeof(History<int, 3>)) << "\n";
}
3 of 3
16
bigger N, bigger object: 1

How it works

This is exactly how std::array<int, 5> works.

Your task: a fixed-size stack

Keep count_ as the number of items. push writes to items_[count_] and increments, unless count_ == N, in which case it returns false. pop decrements first, then returns items_[count_].

Your turn: write template <typename T, std::size_t N> class FixedStack backed by a plain array T items_[N]:

Previous: if constexpr Next: Template specialization