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.