struct A { }; template<class T> struct B { template<class R> int operator*(R&); // #1 }; template<class T, class R> int operator*(T&, R&); // #2 // The declaration of B::operator* is transformed into the equivalent of // template<class R> int operator*(B<A>&, R&); // #1a int main() { A a; B<A> b; b * a; // calls #1a }
template<class T> struct A { A(); }; template<class T> void f(T); template<class T> void f(T*); template<class T> void f(const T*); template<class T> void g(T); template<class T> void g(T&); template<class T> void h(const T&); template<class T> void h(A<T>&); void m() { const int* p; f(p); // f(const T*) is more specialized than f(T) or f(T*) float x; g(x); // ambiguous: g(T) or g(T&) A<int> z; h(z); // overload resolution selects h(A<T>&) const A<int> z2; h(z2); // h(const T&) is called because h(A<T>&) is not callable }
template<class T> void f(T); // #1 template<class T> void f(T*, int=1); // #2 template<class T> void g(T); // #3 template<class T> void g(T*, ...); // #4
int main() { int* ip; f(ip); // calls #2 g(ip); // calls #4 }
template<class T, class U> struct A { }; template<class T, class U> void f(U, A<U, T>* p = 0); // #1 template< class U> void f(U, A<U, U>* p = 0); // #2 template<class T > void g(T, T = T()); // #3 template<class T, class... U> void g(T, U ...); // #4 void h() { f<int>(42, (A<int, int>*)0); // calls #2 f<int>(42); // error: ambiguous g(42); // error: ambiguous }
template<class T, class... U> void f(T, U...); // #1 template<class T > void f(T); // #2 template<class T, class... U> void g(T*, U...); // #3 template<class T > void g(T); // #4 void h(int i) { f(&i); // error: ambiguous g(&i); // OK: calls #3 }