3

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?

2
  • 3
    If the size was variable it would be the same as a std::vector Commented Aug 1, 2020 at 9:01
  • 1
    Generics is not the whole point of templates.
    – molbdnilo
    Commented Aug 1, 2020 at 9:09

2 Answers 2

3

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.

2

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.

Not the answer you're looking for? Browse other questions tagged or ask your own question.