Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reason for using non-type template parameter instead of regular parameter?

Tags:

c++

templates

In C++ you can create templates using a non-type template parameter like this:

template< int I > void add( int& value ) {   value += I; }  int main( int argc, char** argv ) {   int i = 10;   add< 5 >( i );   std::cout << i << std::endl; } 

Which prints "15" to cout. What is the use for this? Is there any reason for using a non-type template parameter instead of something more conventional like:

void add( int& value, int amount ) {   value += amount; } 

Sorry if this has already been asked (I looked but couldn't find anything).

like image 231
Chris Vig Avatar asked Sep 13 '11 00:09

Chris Vig


People also ask

What is non-type template parameters?

A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument. A non-type parameter can be any of the following types: An integral type. An enumeration type. A pointer or reference to a class object.

Why do we use template template parameter?

Why we use :: template-template parameter? Explanation: It is used to adapt a policy into binary ones.

Can we use non-type parameters as arguments template?

Non-type template arguments are normally used to initialize a class or to specify the sizes of class members. For non-type integral arguments, the instance argument matches the corresponding template parameter as long as the instance argument has a value and sign appropriate to the parameter type.

What can be passed by non-type template parameters during?

What can be passed by non-type template parameters during compile time? Explanation: Non-type template parameters provide the ability to pass a constant expression at compile time. The constant expression may also be an address of a function, object or static class member.


1 Answers

There are many applications for non-type template arguments; here are a few:

You can use non-type arguments to implement generic types representing fixed-sized arrays or matrices. For example, you might parameterize a Matrix type over its dimensions, so you could make a Matrix<4, 3> or a Matrix<2, 2>. If you then define overloaded operators for these types correctly, you can prevent accidental errors from adding or multiplying matrices of incorrect dimensions, and can make functions that explicitly communicate the expected dimensions of the matrices they accept. This prevents a huge class of runtime errors from occur by detecting the violations at compile-time.

You can use non-type arguments to implement compile-time function evaluation through template metaprogramming. For example, here's a simple template that computes factorial at compile-time:

template <unsigned n> struct Factorial {     enum {         result = n * Factorial<n - 1>::result     }; }; template <> struct Factorial<0> {     enum {        result = 1     }; }; 

This allows you to write code like Factorial<10>::result to obtain, at compile-time, the value of 10!. This can prevent extra code execution at runtime.

Additionally, you can use non-type arguments to implement compile-time dimensional analysis, which allows you to define types for kilograms, meters, seconds, etc. such that the compiler can ensure that you don't accidentally use kilograms where you meant meters, etc.

Hope this helps!

like image 186
templatetypedef Avatar answered Sep 16 '22 21:09

templatetypedef