http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49637
Timothy J Giese <timothyjgiese at gmail dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED Resolution| |INVALID --- Comment #11 from Timothy J Giese <timothyjgiese at gmail dot com> 2011-07-05 21:05:54 UTC --- These were some useful explanations - thanks gang. I'm going to go ahead and close this because it seems clear now that what g++ is doing is not incorrect. To close this off, I'm going to show a work-around for the original minimal test case, just in case someone lands here from a search engine with a similar problem: #include <iostream> template <class T,class U> struct TypeMatch { static bool const value = false; }; template <class T> struct TypeMatch<T,T> { static bool const value = true; }; // Create 2 functions with different names struct S { typedef int iterator; }; template <class T,class U> void FU (typename T::iterator,U ) { std::cout << "FU" << std::endl; }; template <class T> void Fint(typename T::iterator,int) { std::cout << "Fint" << std::endl; }; // Create a selector function that acts like an overload template <class T,class U> inline void F( typename T::iterator i, U u ) { if ( TypeMatch<int,U>::value ) { Fint<T>(i,u); } else { FU<T,U>(i,u); }; }; // Disadvantage = every new "overload" needs to be inserted into F // However; I won't run into this with my immediate use-case, so I'm not going to complain too hard int main() { S::iterator i(42); F<S>(i,1); // Compiles OK; prints "Fint" F<S>(i,true); // Compiles OK; prints "FU" return 0; }; This work-around compiles fine on g++ 4.6.0.