Introduction to Core C++ Lecture 04: Template Functions and Template Classes Massimiliano Culpo 1 1 CINECA - SuperComputing Applications and Innovation Department 26.02.2013 M.Culpo (CINECA) Introduction to C++ 26.02.2013 1 / 19
Template declarations Template declarations ( 14) A template defines a family of classes or functions: 1 template <typename T> 2 T const& max (T const& a, T const& b ) { 3 // i f a < b then use b e l s e use a 4 return a < b? b : a ; 5 } A template declaration shall: declare or define a function or a class define a member function, a member class or a static data member define a member template of a class or class template A template declaration is also a definition if its declaration defines a function, a class, or a static data member. M.Culpo (CINECA) Introduction to C++ 26.02.2013 2 / 19
Template parameters ( 14.1) Template parameters There are three kinds of allowed template parameters: non-type template parameters, type template parameters and template template parameters. A non-type template parameter shall be either an integral or enumeration type, a pointer/reference to object or function or a pointer to member. 1 template<const X& x, i n t i > void f ( ) { 2 i ++; // e r r o r 3 &x ; // OK 4 &i ; // e r r o r 5 i n t& r i = i ; // e r r o r 6 const i n t& c r i = i ; // OK 7 } A non-type template parameter cannot be assigned to or in any other way have its value changed. M.Culpo (CINECA) Introduction to C++ 26.02.2013 3 / 19
Template parameters ( 14.1) Template parameters The keyword class followed by an unqualified-id names a type parameter: 1 template<c l a s s K, c l a s s V> c l a s s Map { 2 std : : vector<k> key ; 3 std : : vector<v> value ; 4 } ; Template classes may also be used as template parameters: 1 template<c l a s s K, c l a s s V, 2 template<c l a s s T> c l a s s C > c l a s s Map { 3 C<K> key ; 4 C<V> value ; 5 } ; M.Culpo (CINECA) Introduction to C++ 26.02.2013 4 / 19
Template parameters ( 14.1) Template parameters A default argument may be specified for any kind of template parameter: 1 template<c l a s s T1, c l a s s T2 = int > c l a s s A; 2 3 template <c l a s s T = f l o a t > s t r u c t B { } ; 4 template <template <c l a s s TT = f l o a t > c l a s s T> 5 s t r u c t A { 6 i n l i n e void f ( ) ; 7 i n l i n e void g ( ) ; 8 } ; 9 template <template <c l a s s TT> c l a s s T> 10 void A<T>:: f ( ) { T<> t ; } // e r r o r 11 template <template <c l a s s TT = char> c l a s s T> 12 void A<T>:: g ( ) { T<> t ; } // OK T<char> M.Culpo (CINECA) Introduction to C++ 26.02.2013 5 / 19
Function templates Function templates ( 14.5.6) A function template defines an unbounded set of related functions: 1 // s o r t. hxx 2 template<c l a s s T> void s o r t ( T& input ) ; A function template can be overloaded: 1 with other function templates 2 with normal functions The mere use of a function template can trigger an instantiation: 1 #i n clude s o r t. hxx 2 std : : vector< double > vec ; 3 s o r t ( vec ) ; M.Culpo (CINECA) Introduction to C++ 26.02.2013 6 / 19
Function templates Overloading of function templates ( 14.5.6) 1 // max. hxx 2 3 // maximum of two i n t v a l u e s 4 i n l i n e i n t const& max ( i n t const& a, i n t const& b ) 5 { r e t u r n a<b?b : a ; } 6 7 // maximum of two v a l u e s of any type 8 template <typename T> 9 i n l i n e T const& max (T const& a, T const& b ) 10 { r e t u r n a<b?b : a ; } 11 12 // maximum of three v a l u e s of any type 13 template <typename T> 14 i n l i n e T const& 15 max (T const& a, T const& b, T const& c ) 16 { r e t u r n max (max( a, b ), c ) ; } M.Culpo (CINECA) Introduction to C++ 26.02.2013 7 / 19
Function templates Overloading of function templates ( 14.5.6) 1 #i n c l u d e max. hxx 2 3 i n t main ( ) { 4 : : max(7, 42, 6 8 ) ; // template f o r three arguments 5 : : max ( 7. 0, 4 2. 0 ) ; // max<double> 6 : : max( a, b ) ; // max<char> 7 : : max(7, 4 2 ) ; // non template f o r two i n t s 8 : : max<>(7, 4 2 ) ; // max<i n t > 9 : : max<double >(7, 4 2 ) ; // max<double> 10 : : max( a, 4 2. 7 ) ; // non template f o r two i n t s 11 } M.Culpo (CINECA) Introduction to C++ 26.02.2013 8 / 19
Class templates ( 14.5.1) Class templates A class template defines an unbounded set of related types: 1 template<c l a s s T> c l a s s Array { 2 T v ; 3 i n t sz ; 4 p u b l i c : 5 e x p l i c i t Array ( i n t ) ; 6 T& operator [ ] ( i n t ) ; 7 T& elem ( i n t i ) { r e t u r n v [ i ] ; } 8 } ; A member function may be defined outside the class in which it is declared: 1 template<c l a s s T> T& Array<T>:: operator [ ] ( i n t i ) { 2 i f ( i <0 sz<=i ) e r r o r ( Array : range e r r o r ) ; 3 r e t u r n v [ i ] ; 4 } M.Culpo (CINECA) Introduction to C++ 26.02.2013 9 / 19
Class templates ( 14.5.1) Class templates Similar rules apply to class member: 1 template<c l a s s T> s t r u c t A { c l a s s B; } ; 2 A<i n t >::B b1 ; 3 template<c l a s s T> c l a s s A<T>::B { } ; 4 A<i n t >::B b2 ; For a member function of a class template: 1 Array<i n t > v1 ( 2 0 ) ; 2 Array<dcomplex> v2 ( 3 0 ) ; 3 // Array<i n t >:: operator [ ] ( ) 4 v1 [ 3 ] = 7 ; 5 // Array<dcomplex >:: operator [ ] ( ) 6 v2 [ 3 ] = dcomplex ( 7, 8 ) ; the template arguments are determined by the type of the object for which the member function is called. M.Culpo (CINECA) Introduction to C++ 26.02.2013 10 / 19
Member template ( 14.5.2) Class templates A template can be declared within a class or class template: 1 template<c l a s s T> s t r u c t s t r i n g { 2 3 template<c l a s s T2> 4 i n t compare ( const T2&); 5 6 template<c l a s s T2> 7 s t r i n g ( const s t r i n g <T2>& s ) 8 { /... / } 9 } ; 10 11 template<c l a s s T> template<c l a s s T2> 12 i n t s t r i n g <T>:: compare ( const T2& s ) 13 { /... / } M.Culpo (CINECA) Introduction to C++ 26.02.2013 11 / 19
Class templates Member template ( 14.5.2) A local class shall not have member templates. A member function template: 1 shall not be virtual 2 does not override a virtual function 1 template <c l a s s T> s t r u c t AA { 2 template <c l a s s C> v i r t u a l void g (C ) ; // e r r o r 3 } ; 4 c l a s s B { 5 v i r t u a l void f ( i n t ) ; 6 } ; 7 c l a s s D : p u b l i c B { 8 template <c l a s s T> void f (T) ; // no o v e r r i d e 9 void f ( i n t i ) { f <>( i ) ; } // o v e r r i d i n g 10 } ; M.Culpo (CINECA) Introduction to C++ 26.02.2013 12 / 19
Class templates Class template partial specialization ( 14.5.5) A class template may be partially specialized: 1 template<c l a s s T1, c l a s s T2, i n t I> 2 c l a s s A { } ; // Primary c l a s s template 3 4 template<c l a s s T, i n t I> 5 c l a s s A<T, T, I> { } ; // #1 6 7 template<c l a s s T1, c l a s s T2, i n t I> 8 c l a s s A<T1, T2, I> { } ; // #2 Each class template partial specialization is a distinct template and definitions shall be provided for its members. M.Culpo (CINECA) Introduction to C++ 26.02.2013 13 / 19
The typename keyword ( 14.6) Name resolution The keyword typename clarifies that an identifier is a type: 1 template <c l a s s T> 2 c l a s s A { 3 typename T : : SubType ptr ; 4 /... / 5 } ; Without typename, the expression: 1 T : : SubType ptr ; would be a multiplication of a static member of class T with ptr. In general, typename has to be used whenever a name that depends on a template parameter is a type. M.Culpo (CINECA) Introduction to C++ 26.02.2013 14 / 19
The.template construct ( 14.6) Name resolution Consider the following example: 1 template <c l a s s T> c l a s s C { 2 p u b l i c : 3 template<c l a s s U> s t r i n g i f y ( ) ; 4 } 5 6 template<i n t N> 7 void p r i n t (C<N> const& bs ) { 8 cout << bs. template s t r i n g i f y <char >(); 9 } Without that extra use of template, the compiler can t deduce the meaning of the < token. M.Culpo (CINECA) Introduction to C++ 26.02.2013 15 / 19
Dependent names ( 14.6.2) Name resolution If a base class depends on a template parameter, the base class scope is not examined during unqualified name lookup: 1 typedef double A; 2 3 template<c l a s s T> c l a s s B { 4 typedef i n t A; 5 } ; 6 7 template<c l a s s T> s t r u c t X : B<T> { 8 A a ; // a has type double 9 } ; The consequence is that using a name x by itself is not always equivalent to this >x. M.Culpo (CINECA) Introduction to C++ 26.02.2013 16 / 19
String literals Template functions Name resolution Q: Can you explain the following behavior? 1 template <typename T> i n l i n e T const& 2 max (T const& a, T const& b ) { 3 return a < b? b : a ; 4 } 5 6 i n t main ( ) { 7 s t r i n g s ; 8 : : max( a p p l e, peach ) ; // OK 9 : : max( a p p l e, tomato ) ; // ERROR 10 : : max( a p p l e, s ) ; // ERROR 11 } M.Culpo (CINECA) Introduction to C++ 26.02.2013 17 / 19
Explicit instantiation ( 14.8.1) Name resolution An empty template argument list can be used to indicate that a given use refers to a specialization of a function template: 1 template <c l a s s T> i n t f (T) ; // #1 2 i n t f ( i n t ) ; // #2 3 i n t k = f ( 1 ) ; // uses #2 4 i n t l = f < >(1); // uses #1 Implicit conversions will be performed if the parameter type contains no parameters that participate in template argument deduction: 1 template<c l a s s T> void f (T) ; 2 c l a s s Complex { 3 Complex ( double ) ; 4 } ; 5 void g ( ) { 6 f<complex >(1); // OK 7 } M.Culpo (CINECA) Introduction to C++ 26.02.2013 18 / 19
Summary overview of name resolution Summary: stages of function name resolution When a function name is to be resolved: 1 foo ( 1 2, 4 5 ) ; the C++ machinery goes through a number of codified stages: 1. (compile-time) Name lookup ( 3.4) 2. (compile-time) Template argument deduction ( 14.8.2) 3. (compile-time) Overload resolution ( 13) 4. (compile-time) Access control ( 11) 5. (run-time) Virtual function resolution ( 10.3-10.4) It is important to know the subtleties of each of these stages to avoid common pitfalls. M.Culpo (CINECA) Introduction to C++ 26.02.2013 19 / 19