Non-type template parameters are consumed at compile time, and instantiating a template with a unique value creates a new type or function. This information can then be used for "configuration" that is impossible at run time. This is somewhat horizontal to a template type - a class template parameter T
achieves reusability w.r.t. different types, while non-type template parameters offer a different kind of reusability.
std::array
is a good example for that. I assume its class definition has a data member that is a plain array with the size N
, e.g.
template<class T, std::size_t N>
struct array {
// ...
T wrapped[N];
};
If N
was a runtime value (e.g. passed to a constructor), there is no way to do such things.
Another example where such compile-time "configuration" of class templates is useful are "small vectors", i.e., containers that have a fixed buffer size, postponing dynamic memory allocation to the point where that buffer is full. Such buffer size can also only be specified with a non-type template parameter. And given that memory allocation can be a performance bottleneck, such techniques are of great importance.
std::vector