http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57043
Jason Merrill <jason at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jason at gcc dot gnu.org --- Comment #3 from Jason Merrill <jason at gcc dot gnu.org> --- OK, this is puzzling. The issue is that GCC can't tell that the first pow is more specialized than the second; deduction happens fine, but when we substitute in Tp(1) for Tp(2) and Up we still have complex<typename promote_2<Tp(1), Tp(1)>::type> for the return type, which looks different from complex<Tp(1)>, so deduction fails and we decide it isn't more specialized. I can't figure out what interpretation of the standard clang/EDG are using to make this work. Are they actually instantiating promote_2? That doesn't seem to be it, as they also accept the following, which seems clearly unordered to me: template<typename D> struct complex { }; template <class T> struct promote_1 { typedef T type; }; template<typename T, typename U> struct promote_2 { typedef T type; }; template<typename Tp> complex<typename promote_1<Tp>::type> pow(const complex<Tp>& x, const complex<Tp>& y); template<typename Tp, typename Up> complex<typename promote_2<Tp, Up>::type> pow(const complex<Tp>& x, const complex<Up>& y); complex<double> (*powcc)(const complex<double>&, const complex<double>&) = pow;