C++ Templates Non-type template parameter


Apart from types as a template parameter we are allowed to declare values of constant expressions meeting one of the following criteria:

  • integral or enumeration type,
  • pointer to object or pointer to function,
  • lvalue reference to object or lvalue reference to function,
  • pointer to member,
  • std::nullptr_t.

Like all template parameters, non-type template parameters can be explicitly specified, defaulted, or derived implicitly via Template Argument Deduction.

Example of non-type template parameter usage:

#include <iostream>

template<typename T, std::size_t size>
std::size_t size_of(T (&anArray)[size])  // Pass array by reference. Requires.
{                                        // an exact size. We allow all sizes
    return size;                         // by using a template "size".

int main()
    char anArrayOfChar[15];
    std::cout << "anArrayOfChar: " << size_of(anArrayOfChar) << "\n";

    int  anArrayOfData[] = {1,2,3,4,5,6,7,8,9};
    std::cout << "anArrayOfData: " << size_of(anArrayOfData) << "\n";

Example of explicitly specifying both type and non-type template parameters:

#include <array>
int main ()
    std::array<int, 5> foo; // int is a type parameter, 5 is non-type

Non-type template parameters are one of the ways to achieve template recurrence and enables to do Metaprogramming.