https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72752
--- Comment #1 from Michael <mikeus at hotmail dot ru> --- When it is explicitly specified to use a default template argument the code is compiled successfully: ----- 8< ---------- 8< ---------- 8< ----- typedef void (*foo_t)(); void test(foo_t) {} template< typename > struct A { template< typename = void > static void foo(); void bar() { test(foo<>); } template< typename > void baz() { test(foo<>); } }; template< typename _T_ > template< typename > void A< _T_ >::foo() {} ----- >8 ---------- >8 ---------- >8 ----- Here is a variation for one more test case: ICE generated: ----- 8< ---------- 8< ---------- 8< ----- typedef void (*foo_t)(); void test(foo_t, foo_t) {} template< typename > struct A { template< typename = void > static void foo1(); template< typename = void > static void foo2(); void bar() { test(foo1, foo2); } template< typename > void baz() { test(foo1, foo2); } }; template< typename _T_ > template< typename > void A< _T_ >::foo1() {} template< typename _T_ > template< typename > void A< _T_ >::foo2() {} ----- >8 ---------- >8 ---------- >8 ----- Successfully passed: ----- 8< ---------- 8< ---------- 8< ----- typedef void (*foo_t)(); void test(foo_t, foo_t) {} template< typename > struct A { template< typename = void > static void foo1(); template< typename = void > static void foo2(); void bar() { test(foo1, foo2<>); } template< typename > void baz() { test(foo1<>, foo2); } }; template< typename _T_ > template< typename > void A< _T_ >::foo1() {} template< typename _T_ > template< typename > void A< _T_ >::foo2() {} ----- >8 ---------- >8 ---------- >8 -----