Variadic Templates Frej Soya Jorgen Haahr May 9, 2008 What is - - PowerPoint PPT Presentation
Variadic Templates Frej Soya Jorgen Haahr May 9, 2008 What is - - PowerPoint PPT Presentation
Variadic Templates Frej Soya Jorgen Haahr May 9, 2008 What is Variadic Templates? Variable number of template parameters Short example template < typename . . . Values > c l a s s t u p l e ; main () { i n t tuple < int ,
What is ”Variadic Templates”?
- Variable number of template parameters
Short example
template <typename . . . Values> c l a s s t u p l e ; i n t main () { tuple <int , double , char const ∗> something (1 ,
- 2. 2 ,
” t e s t ” ) ; return 0; }
Motivation
- Fixed numbers of template parameters
Motivation
- Fixed numbers of template parameters
- Emulating variable number of template parameters with
preprocessing
Motivation
- Fixed numbers of template parameters
- Emulating variable number of template parameters with
preprocessing
- printf is not typesafe.
Motivation
- Fixed numbers of template parameters
- Emulating variable number of template parameters with
preprocessing
- printf is not typesafe.
- tuples in boost has limited size.
Motivation
- Fixed numbers of template parameters
- Emulating variable number of template parameters with
preprocessing
- printf is not typesafe.
- tuples in boost has limited size.
- Improves argument forwarding for variable arguments.
Fixing printf (and varargs) in c++
printf crashes on non-POD
p r i n t f ( ” H e l l o %s ” , std : : s t r i n g ( ”World” ) )
Good compilers warn you.
With variadic templates
void p r i n t f ( const char∗ s ) { while (∗ s ) { i f (∗ s == ’%’ && ∗++s != ”%” ) throw . . . . std : : cout < < ∗s++; } }
continued...
template<typename T, typename . . . Args> void p r i n t f ( const char∗ s ,T value , Args . . . args ) { while (∗ s ) { i f (∗ s == ’%’ && ∗++s != ’%’ ) { std : : cout < < v a l u e ; return p r i n t f (++s , args . . . ) ; } std : : cout < < ∗s++; } throw std : : runtime e r r o r ( ” e x t r a arguments pr ov ided to p r i n t f ” ) ; }
What just happened?
- The ellipsis operator ”...”
- Parameter packs
- Parameter packing
- Parameter unpacking
- Typeinformation is retained
Example
i n t count () { return 0;} template <typename T, typename . . . Args> i n t count (T head , Args . . . t a i l ) { return 1+count ( t a i l . . . ) ; } i n t main () { cout < < count<int , double , double >(1 ,2.3 , 3 . 5 ) ; }
Shortcut for count
const int size = sizeof(Args..)
Tuples
template<typename Head , typename . . . Tail > c l a s s tuple <Head , T a i l ... > : p r i v a t e tuple <T a i l ... > { Head head ; };
Different sized tuples
template<typename . . Elements1 , typename . . . Elements2> bool
- perator==(const
tuple <Elements1 . . . & t1 , const tuple < Elements2 ... >& t2 ) ;
Equally sized tuples
template<typename . . Elements> bool
- perator==(const
tuple <Elements . . . & t1 , const tuple < Elements ... >& t2 ) ;
Initializer lists
- Interaction with generalized initializer lists
template<typename . . . Values> c l a s s t u p l e { p u b l i c : t u p l e ( const Values & . . . v a l u e s ) ; };
This is nice for tuples
tuple <int , f l o a t , s t r i n g > t = {42 , 2.71828 , ” Hello , world ! ”}
Usage
- No imperative access to types
- Use is often recursive
- E.g. count and printf functions
- However, by using the unpacking operator the template