https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103096
--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Jonathan Wakely from comment #4) > Maybe the compiler could notice that there is only one qHash function > template, and so realize that the instantiation recursion of qHash<X> > instantiating qHash<Y> instantiating qHash<Z> etc. will never terminate. It would also have to consider whether there are partial or explicit specializations of the pair class template, because otherwise one of them could define a friend that would be found by ADL and terminate the recursion. So maybe too hard. This case is fine: template<typename T, typename U> struct pair { pair(const T& t, const U& u) : first(t), second(u) { } T first; U second; }; template <typename T> int qHash(const T& a) { return qHash(pair<T, T>(a, a)); } template<typename T> struct pair<pair<pair<T, T>, pair<T, T>>, pair<pair<T, T>, pair<T, T>>> { template<typename... X> pair(X...) { } friend int qHash(pair) { return 0; } }; void f(int); int main() { int a = 3; f(qHash(a)); } The overload of qHash that terminates the recursion is only defined when the partial specialization is instantiated.