4

What does it mean to define a template with template <int N>, I read this from an example in a book:

typedef map<int, double> row;
template <int N> struct matrix;
{
   map <int, row> my_matrix;
}

I have usually seen templates which are followed by class and then type, i.e. template <class int>

James Hallen
  • 4,534
  • 4
  • 23
  • 28

3 Answers3

16

Template parameters may be of any of the three kinds of C++ entities: values, types, or templates:

template <int N> struct Foo;                        // N is a value

template <typename T> struct Bar;                   // T is a type

template <template <typename> class X> struct Zip;  // X is a template

Example usage:

Foo<10> a;

Bar<int> b;

Zip<Bar> c;

Note that this corresponds to the three ways of disamiguating dependent names:

X::a = 10;              // X::a is a value
typename X::B n = 10;   // X::B is a type
X::template C<int> m;   // X::C is a template

An interesting combination arises when you want to "typify" a value. This can be done like so:

template <typename T, T Val> struct Typificate;

Now you can say e.g. Typificate<int, 10> to get a unique type that represents the integer 10. This can occasionally be very useful, e.g. when T is a member function pointer (e.g. in this delegate implementation); or it can be used to create value-unique overloads for tag dispatch, etc.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • I'm still a little confused with the example, suppose we have `template class row { private: name some_name; type some_type; };` The `class name/type` are used to typify variables defined in the class, however, what is the purpose of having `template struct Foo;` what is the `"N"` used for? – James Hallen Jul 16 '14 at 21:27
  • @JamesHallen: It can be used for whatever you want. An obvious example is an array size in some custom array template. – Kerrek SB Jul 16 '14 at 21:28
  • So in such a case, we're not using "N" to typify any variables in the struct, we are using it to initialize an array. For example: `vector my_vector(2);`, using "N" is akin to constructing a vector of size 2 – James Hallen Jul 16 '14 at 21:32
  • 3
    @JamesHallen: Consider `template struct Foo { int a[N]; };` – Kerrek SB Jul 16 '14 at 21:45
  • Sorry, another question from my code above: if I declared `matrix<5> temp;`, would that create 5 elements of `my_matrix`, in other words I have access to `temp.my_matrix[0]`, `temp.my_matrix[1]`...`temp.my_matrix[4]`? – James Hallen Jul 18 '14 at 18:53
  • @JamesHallen: No, why would it do that -- `matrix<5>` has only one member, `map my_matrix`. If you want an array, you need to declare an array. – Kerrek SB Jul 18 '14 at 20:00
1

It will provide a int constant value that is evaluated at compile time

template <int N> struct matrix {
   static const int MatrixSize = N;
   map <int, row> my_matrix;
};

matrix<10>::MatrixSize; // Yields 10
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
1

That is a non-type template parameter. A parameter in the parameter list of a template can be either a non-type parameter, a type parameter or a template parameter. In your example it is the first. For more information see Template parameters and template arguments.

A non-type template argument is normally used to initialize a class or to specify the sizes of class members. According to the standard (14.1 [temp.param]) a non-type template parameter can have one of the following types:

A non-type template-parameter shall have one of the following (optionally cv-qualified) types:

  • 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.
Marius Bancila
  • 16,053
  • 9
  • 49
  • 91