template<class T> void g(T); g({1,2,3}); // error: no argument deduced for T— end example
template<class T> void f(T x, T y) { /* ... */ } struct A { /* ... */ }; struct B : A { /* ... */ }; void g(A a, B b) { f(a,b); // error: T could be A or B f(b,a); // error: T could be A or B f(a,a); // OK: T is A f(b,b); // OK: T is B }
template <class T, class U> void f( T (*)( T, U, U ) ); int g1( int, float, float); char g2( int, float, float); int g3( int, char, float); void r() { f(g1); // OK: T is int and U is float f(g2); // error: T could be char or int f(g3); // error: U could be char or float }
template<class T> void f(const T*) { } int* p; void s() { f(p); // f(const int*) }
template <class T> struct B { }; template <class T> struct D : public B<T> {}; struct D2 : public B<int> {}; template <class T> void f(B<T>&){} void t() { D<int> d; D2 d2; f(d); // calls f(B<int>&) f(d2); // calls f(B<int>&) }— end example
T cv T T* T& T&& T[integer-constant] template-name<T> (where template-name refers to a class template) type(T) T() T(T) T type::* type T::* T T::* T (type::*)() type (T::*)() type (type::*)(T) type (T::*)(T) T (type::*)(T) T (T::*)() T (T::*)(T) type[i] template-name<i> (where template-name refers to a class template) TT<T> TT<i> TT<>where (T) represents a parameter-type-list ([dcl.fct]) where at least one parameter type contains a T, and () represents a parameter-type-list where no parameter type contains a T.
template<class T1, class... Z> class S; // #1 template<class T1, class... Z> class S<T1, const Z&...> { }; // #2 template<class T1, class T2> class S<T1, const T2&> { }; // #3 S<int, const int&> s; // both #2 and #3 match; #3 is more specialized template<class T, class... U> struct A { }; // #1 template<class T1, class T2, class... U> struct A<T1, T2*, U...> { }; // #2 template<class T1, class T2> struct A<T1, T2> { }; // #3 template struct A<int, int*>; // selects #2— end example
template <class T> void f(T&&); template <> void f(int&) { } // #1 template <> void f(int&&) { } // #2 void g(int i) { f(i); // calls f<int&>(int&), i.e., #1 f(0); // calls f<int>(int&&), i.e., #2 }— end example
template<class T, class... U> void f(T*, U...) { } // #1 template<class T> void f(T) { } // #2 template void f(int*); // selects #1— end example
template<long n> struct A { }; template<typename T> struct C; template<typename T, T n> struct C<A<n>> { using Q = T; }; using R = long; using R = C<A<2>>::Q; // OK; T was deduced as long from the // template argument value in the type A<2>— end example
template<typename T> struct S; template<typename T, T n> struct S<int[n]> { using Q = T; }; using V = decltype(sizeof 0); using V = S<int[42]>::Q; // OK; T was deduced as std::size_t from the type int[42]— end example
template<class T, T i> void f(int (&a)[i]); int v[10]; void g() { f(v); // OK: T is std::size_t }— end example
template<int i> void f1(int a[10][i]); template<int i> void f2(int a[i][20]); template<int i> void f3(int (&a)[i][20]); void g() { int v[10][20]; f1(v); // OK: i deduced as 20 f1<20>(v); // OK f2(v); // error: cannot deduce template-argument i f2<10>(v); // OK f3(v); // OK: i deduced as 10 }
template <int i> class A { /* ... */ }; template <int i> void g(A<i+1>); template <int i> void f(A<i>, A<i+1>); void k() { A<1> a1; A<2> a2; g(a1); // error: deduction fails for expression i+1 g<0>(a1); // OK f(a1, a2); // OK }— end example
template<int i, typename T> T deduce(typename A<T>::X x, // T is not deduced here T t, // but T is deduced here typename B<i>::Y y); // i is not deduced here A<int> a; B<77> b; int x = deduce<77>(a.xm, 62, b.ym); // T deduced as int; a.xm must be convertible to A<int>::X // i is explicitly specified to be 77; b.ym must be convertible to B<77>::Y— end note
template<int i> class A { /* ... */ }; template<short s> void f(A<s>); void k1() { A<1> a; f(a); // error: deduction fails for conversion from int to short f<1>(a); // OK } template<const short cs> class B { }; template<short s> void g(B<s>); void k2() { B<1> b; g(b); // OK: cv-qualifiers are ignored on template parameter types }— end example
template<class T> void f(void(*)(T,int)); template<class T> void foo(T,int); void g(int,int); void g(char,int); void h(int,int,int); void h(char,int); int m() { f(&g); // error: ambiguous f(&h); // OK: void h(char,int) is a unique match f(&foo); // error: type deduction fails because foo is a template }— end example
template <class T> void f(T = 5, T = 7); void g() { f(1); // OK: call f<int>(1,7) f(); // error: cannot deduce T f<int>(); // OK: call f<int>(5,7) }— end example
template <template <class T> class X> struct A { }; template <template <class T> class X> void f(A<X>) { } template<class T> struct B { }; A<B> ab; f(ab); // calls f(A<B>)— end example
template<class> struct X { }; template<class R, class ... ArgTypes> struct X<R(int, ArgTypes ...)> { }; template<class ... Types> struct Y { }; template<class T, class ... Types> struct Y<T, Types& ...> { }; template<class ... Types> int f(void (*)(Types ...)); void g(int, float); X<int> x1; // uses primary template X<int(int, float, double)> x2; // uses partial specialization; ArgTypes contains float, double X<int(float, int)> x3; // uses primary template Y<> y1; // use primary template; Types is empty Y<int&, float&, double&> y2; // uses partial specialization; T is int&, Types contains float, double Y<int, float, double> y3; // uses primary template; Types contains int, float, double int fv = f(g); // OK; Types contains int, float— end example