template<class T> void sort(Array<T>& v); void f(Array<dcomplex>& cv, Array<int>& ci) { sort<dcomplex>(cv); // sort(Array<dcomplex>&) sort<int>(ci); // sort(Array<int>&) }
template<class U, class V> U convert(V v); void g(double d) { int i = convert<int,double>(d); // int convert(double) char c = convert<char,double>(d); // char convert(double) }
template<class X, class Y> X f(Y); template<class X, class Y, class ... Z> X g(Y); void h() { int i = f<int>(5.6); // Y is deduced to be double int j = f(5.6); // ill-formed: X cannot be deduced f<void>(f<int, bool>); // Y for outer f deduced to be int (*)(bool) f<void>(f<int>); // ill-formed: f<int> does not denote a single function template specialization int k = g<int>(5.6); // Y is deduced to be double, Z is deduced to an empty sequence f<void>(g<int, bool>); // Y for outer f is deduced to be int (*)(bool), // Z is deduced to an empty sequence }
template <class T> int f(T); // #1 int f(int); // #2 int k = f(1); // uses #2 int l = f<>(1); // uses #1
template<class X, class Y, class Z> X f(Y,Z); template<class ... Args> void f2(); void g() { f<int,const char*,double>("aa",3.0); f<int,const char*>("aa",3.0); // Z is deduced to be double f<int>("aa",3.0); // Y is deduced to be const char*, and Z is deduced to be double f("aa",3.0); // error: X cannot be deduced f2<char, short, int, long>(); // OK }
namespace A { struct B { }; template<int X> void f(B); } namespace C { template<class T> void f(T t); } void g(A::B b) { f<3>(b); // ill-formed: not a function call A::f<3>(b); // well-formed C::f<3>(b); // ill-formed; argument dependent lookup applies only to unqualified names using C::f; f<3>(b); // well-formed because C::f is visible; then A::f is found by argument dependent lookup }
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}