http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56421
--- Comment #13 from Kristian Spangsege <kristian.spangsege at gmail dot com> 2013-02-22 23:46:04 UTC --- Jonathan, "The complete set" is the set *before* the number of arguments is considered to find the viable subset. To synthesize the declaration Foo<int>::type must be known, and that type results in an error. Why then is the following accepted (replaced "Foo<S>::type" with "S::type"): template<class S> struct Foo { typedef typename S::type type; }; template<class> void foo(); template<class S> typename S::type foo(int); int main() { foo<int>(); }