template< class, class = void > struct has_type_member : false_type { };
In your structure template, by default, two template arguments are specified, and the second is set to void by default, so this argument does not need to be specified explicitly as a function parameter by default.
Then:
template< class T > struct has_type_member<T, void_t<typename T::type>> : true_type { };
Is the template specification for your has_type_member structure, SFINAE will exclude this specialization if T::type does not exist (and therefore is invalid syntax), if it exists, it will choose this specialization differently.
The second parameter must be used to specialize the template, but we do not use it in our "backup" struct , so we are just void by default.
Sombrero chicken
source share