Tuesday, 13 August 2013

Non-type template parameters

Generally in class as well as function templates the parameters are of generic type T. But they don't have to be. The params can be non-type params or type of the param can be fixed. e.g.

template <typename T, int MAX>
class Stack 
{
public:
         void push(const T&);
         ...
private:
          T [MAX];
         ... 
}; //stack with fixed number of elements.

template<typename T, int MAX>
void Stack<T,MAX>::push(const T&) {...} //function definition. 

In function definition outside the class, both the params should be specified.

//usage

main()
{
...
Stack<int, 20> intStack20;
Stack<std::string, 40> stringStack40;
...
}


Default values:

Default values can also be specified for non type template params e.g.

template <typename = int, int MAX =100>
class Stack { ... } 

//use 
main()
{
       Stack mystack; //stack of 100 ints.
}

But this is not a good idea from generic programming point of view, this way you are restricting the generalisation and this warrants documentation of default params.

Default values for function templates (Functors):

template <typename T, int NUM=1>
T addNUM(const T& val)
{
      return val + NUM;
}

//use

main()
{
...
//assume vec is a vector of ints

//adds 20 to every element in vec but results are lost as they are not stored in //vec - use transform instead main point is to demo default values in function templates for non type template params.

for_each( vec.begin(), vec.end(), addNUM<int,20>);
...
//assume dvec is a vector of doubles
...
//adds 1 (by default) to every element of dvec.
for_each(dvec.begin(), dvec.end(), addNUM<double>);
...

}

Restrictions on non type template parameters.

  • They may be const integral values including pointers to objects with external linkage.
  • floating points numbers and class type objects are not allowed.
//ERROR: double not allowed
template <double TEST> double calc(double v) { return v*TEST;}

//ERROR: class type objects not allowed.
template <std::string str> class Myclass {...};

template <typename const char* name>
class MyName{...};

MyName<"Mandar"> x; //ERROR: string literal is not allowed.

const char* s="Mandar";
MyName<s> x; //ERROR: s is a pointer to object with internal linkage.

extern const char s[] ="Mandar";
MyName<s> x; //OK: global array with external linkage.

No comments:

Post a Comment