C++ templates allow you to write a single piece of code that works for multiple types.
For example:
mylist<int> a; a.add( 3 ); // ok a.add( "foo" ); // compile error
Also, C++ templates don't only use types:
// Make something that adds 3 adder<3> add3; // This prints 5 cout << add3.doit( 2 ) << endl;
Also, C++ templates do specialisation.
Also, C++ templates do specialisation.
Which is seriously cool.
Class declaration:
template<int ToAdd> class adder { public: int doit( int x ); };
Class definition:
template<int ToAdd> int adder<ToAdd>::doit( int x ) { return ToAdd + x; }
Specialisation:
template<> class adder<0> { public: int doit( int x ); }; template<> int adder<0>::doit( int x ) { return x; // optimised! }
Let's calculate some things at compile time:
cout << Pow<2, 16>::value << endl; cout << Pow<3, 3>::value << endl;
This prints:
65536 27
Don't believe me?
// h.cpp cout << 65536 << endl; cout << 27 << endl; // c.cpp cout << Pow<2, 16>::value << endl; cout << Pow<3, 3>::value << endl;
Don't believe me?
$ g++ -S h.cpp $ g++ -S c.cpp $ diff -U 0 h.s c.s
--- h.s 2014-03-06 +++ c.s 2014-03-06 @@ -1 +1 @@ - .file "h.cpp" + .file "c.cpp"
template<int B, int E> class Pow { public: static const int value = B * Pow<B, E-1>::value; };
template<int B> class Pow<B, 0> { public: static const int value = 1; };
#define NUM 40 int answer[NUM]; Fib<NUM> ctf( answer );
void fibimpl( int* answer, int n1, int n2, int num ) { if ( num > -1 ) { answer[num] = n1; fibimpl( answer, n2, n1 + n2, num - 1 ); } } void fib( int* answer, int num ) { fibimpl( answer, 1, 1, num - 1 ); }
template<int Num> class Fib { public: Fib( int* answer ); }; template<int Num> Fib<Num>::Fib( int* answer ) { FibImpl<1, 1, Num-1> impl( answer ); }
template<int N1, int N2, int Num> class FibImpl : public FibImpl<N2, N1 + N2, Num - 1> { public: FibImpl( int* answer ); }; template<int N1, int N2> class FibImpl<N1, N2, -1> { public: FibImpl( int* answer ); };
template<int N1, int N2, int Num> FibImpl<N1, N2, Num>::FibImpl( int* answer ) : FibImpl<N2, N1 + N2, Num - 1>( answer ) { answer[Num] = N1; } template<int N1, int N2> FibImpl<N1, N2, -1>::FibImpl( int* answer ) { }
$ g++ -S compile-time-fib.cpp $ grep 4181 compile-time-fib.s | grep movq movq $4181, (%rax) $ grep 1597 compile-time-fib.s | grep movq movq $1597, (%rax)
Videos | youtube.com/user/ajbalaam |
---|---|
@andybalaam | |
Blog | artificialworlds.net/blog |
Projects | artificialworlds.net |