GCC rejects the following code: #include <type_traits> template<bool bar> struct foo{ template<typename T, typename = typename std::enable_if<bar>::type> void fun(T){} }; int main(){ foo<false> var{}; } The error claims: “error: no type named 'type' in 'struct std::enable_if<false, void>”. Which is certainly true but according to my reading of the standard perfectly OK, because the default-arguments of templates must not be instantiated before usage: Section 14.7.1: “...The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions or default arguments, of the class member functions, member classes, scoped member enumerations, static data members and member templates;...“
The standard does not clearly say that. Note that "default arguments" doesn't naturally extend to default *template* arguments. There exists a core language issue in regard to this kind of example, http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1635
Thanks Daniel. Let's suspend this for now.
I think this is resolved by http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html -- in C++23, template default arguments are a complete-class context. Will try to implement this in GCC 12.