Non-type template arguments? Advantages?

closed account (zybCM4Gy)
http://www.cplusplus.com/doc/tutorial/functions2/ Bottom of the page.

I can see the advantage with the first type of template...reduced code...but I can't quite understand in what circumstance that the Non-type template would be useful.

(Though I'm also struggling with the multiple argument template template <class T, class U> as I don't understand the point of that either when the template <class T> works just as well. )
For multiple argument templates, a simple example:

Suppose you wanted to make a "pair" data structure that holds two elements of arbitrary types that are not necessarily the same.
1
2
3
4
5
template <class T, class U>
struct pair {
  T first;
  U second;
};


I can't think of a simple example for non-type template parameters off hand, but perhaps someone else can.
I can think of one use though not sure how important it is since most people use STL containers.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <typeinfo>

template <typename T, std::size_t Rows , std::size_t Columns>
void info( T (&array)[Rows][Columns] )
{
	std::cout << "Array Type: " << typeid(T).name() << std::endl;
	std::cout << "Array Size: " << Rows << 'x' << Columns << std::endl;
}

int main()
{
	int array1[32][1];
	float array2[12][5];
	double array3[7][123];
	
	info(array1);
	info(array2);
	info(array3);
	return 0;
}
Array Type: i
Array Size: 32x1
Array Type: f
Array Size: 12x5
Array Type: d
Array Size: 7x123

http://ideone.com/sQuUlC
Last edited on
Here are a couple more:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <iostream>

template < typename T, std::size_t N > struct checked_array
{
    T a[N] {} ;

    T& operator[] ( std::size_t pos )
    {
        if( pos >= N ) throw "std::out_of_range" ;
        return a[pos] ;
    }

    const T& operator[] ( std::size_t pos ) const
    {
        if( pos >= N ) throw "std::out_of_range" ;
        return a[pos] ;
    }
};

template < std::size_t FROM, std::size_t TILL, typename FN >
struct unroll_loop
{
    unroll_loop( FN fn = FN() ) { fn(FROM) ; unroll_loop< FROM+1, TILL, FN >{fn} ; }
};

template < std::size_t N, typename FN >
struct unroll_loop< N, N, FN >
{
    unroll_loop( FN ) {}
} ;

struct foo
{
    void operator() ( int i ) const 
    { 
        std::cout << "foo(" << i << ")\n" ; 
        
        // ... body of loop 
    }
};

int main()
{
    unroll_loop<1,6,foo>() ;
    
    checked_array<int,10> a ;
    
    try
    {
        std::cout << '\n' << "a[5] == " << a[5] << " fine\n" ;
        std::cout << "a[25] == " << a[25] << " not fine\n" ;
    }
    catch( const char* what ) { std::cerr << what << '\n' ; }
}

http://coliru.stacked-crooked.com/a/80ed4ca168db3691
Topic archived. No new replies allowed.