nick2225
nick2225

Reputation: 555

Why use a non-type parameter in C++?

I was reading the documentation for the array object in C++ here: https://en.cppreference.com/w/cpp/container/array and I saw that the template header was

template<
    class T,
    std::size_t N
> struct array;

Why is N passed as a non-type parameter rather than the struct having a constructor that takes a size as a variable?

What is the purpose of non-type parameters when the whole point of templates is to be used for generic types?

Upvotes: 3

Views: 912

Answers (2)

Lukas-T
Lukas-T

Reputation: 11340

You basically have two array classes in STL:

  • std::vector is a wrapper around a dynamically allocated array. It's size can be changed at runtime and thus can be given in the constructor.

  • std::array on the other hand is a wrapper for a static array (like int values[10];). It's size must be known at compile time and can't be changed at runtime. That's why the size is a template-parameter and can't be passed to the constructor.

Upvotes: 2

lubgr
lubgr

Reputation: 38267

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.

Upvotes: 3

Related Questions