4

I understand the concept but i don't know why i require to use non-type template arguments ?

oiyio
  • 5,219
  • 4
  • 42
  • 54

4 Answers4

15

There are many use-cases, so let's look at a couple of situations where they are indispensable:

  • Fixed sized array or matrix classes, see for example C++11 std::array or boost::array.

  • A possible implementation of std::begin for arrays, or any code that needs the size of a fixed size C style array, for example:

return the size of an array:

template <typename T, unsigned int N>
unsigned int size(T const (&)[N])
{
  return N;
}

They are also extremely useful in template metaprogramming.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
3

A real-world example comes from combining non-type template arguments with template argument deduction to deduce the size of an array:

template <typename T, unsigned int N>
void print_array(T const (&arr)[N])       // both T and N are deduced
{
    std::cout << "[";
    for (unsigned int i = 0; i != N; ++i)
    {
        if (i != 0) { std::cout << ", ";
        std::cout << arr[i];
    }
    std::cout << "]";
}

int main()
{
    double x[] = { 1.5, -7.125, 0, std::sin(0.5) };
    print_array(x);
}
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
2

To program at compile-time. Consider the WikiPedia example,

template <int N>
struct Factorial {
    enum { value = N * Factorial<N - 1>::value };
};

template <>
struct Factorial<0> {
    enum { value = 1 };
};

// Factorial<4>::value == 24
// Factorial<0>::value == 1
const int x = Factorial<4>::value; // == 24
const int y = Factorial<0>::value; // == 1

There are a bunch of other examples on the WikiPedia page.

EDIT

As mentioned in the comments, the above example demonstrates what can be done rather than what people use in real projects.

Hindol
  • 2,924
  • 2
  • 28
  • 41
  • I don't know about you, but "we" don't use it to program at compile time. :\ – user541686 Sep 23 '12 at 07:07
  • 4
    That merely demonstrates how powerful templates are, but does not show how they get used in real code. –  Sep 23 '12 at 07:07
  • I have seen a `Bounded Integer` class somewhere in *SO* but cannot find it now. It allowed custom type creations such as `bounded<0, 255>`. – Hindol Sep 23 '12 at 07:14
  • @Hindol Do you mean http://stackoverflow.com/a/148693/743382 ? Or perhaps http://stackoverflow.com/a/3058733/743382 ? –  Sep 23 '12 at 07:18
  • @hwd The first link is the closest. But I remember seeing a more _complete_ implementation of the same with `type conversions` and stuff such that a `bounded` worked perfectly like an `int`. – Hindol Sep 23 '12 at 07:25
  • I actually do stuff like this in real projects, these techniques are more than purely academic. – juanchopanza Sep 23 '12 at 07:45
  • @juanchopanza Fair enough, though I still suppose that's still far from the most common use. –  Sep 23 '12 at 07:59
0

Another example of non type argument is:

template <int N>
struct A
{
    // Other fields.
    int data[N];
};

Here the length of the data field is parameterised. Different instantiations of this struct can have different lengths of their arrays.

Kirill Kobelev
  • 10,252
  • 6
  • 30
  • 51