Apart from types as a template parameter we are allowed to declare values of constant expressions meeting one of the following criteria:
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.