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
}