https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85765
--- Comment #4 from Casey Carter <Casey at Carter dot net> --- Narrowing the error down: template<class T, class U = decltype(begin(declval<T&>())), decltype(*U(),0) = 0> U g(T& t, long) { return begin(t); } // #1 ---- prog.cc: In instantiation of 'U g(T&, long int) [with T = volatile il; U = int*; decltype (((* U()), 0)) <anonymous> = 0]' The "U = int*" is particularly damning here: it tells us the compiler substituted `volatile il` into `decltype(begin(declval<T&>()))` to get `begin(declval<volatile il&>())`. `int* begin(il);` is a *candidate* for overload resolution - it has the right name and number of parameters - and it's a viable candidate because the ICS from lvalue `volatile il` to `il` is an identity conversion per [over.best.ics]/6: "Any difference in top-level cv-qualification is subsumed by the initialization itself and does not constitute a conversion. ... When the parameter has a class type and the argument expression has the same type, the implicit conversion sequence is an identity conversion." Since it's the *only* viable function, it is unambiguously the *best* viable function. So the only question here is why the compiler omits the final analysis that would determine that initialization of an `il` from a `volatile il&` is ill-formed - making the entire function call expression ill-formed - but only does so when the following `decltype(*U(),0) = 0` is present in the template parameter list.