I intend for my question to be a follow up to: How do we use void_t for SFINAE?. I understand how void_t is used. I do not understand why it is necessary.
Let's take the example from that SO question and remove the void_t
template< class , class = void >
struct has_member : std::false_type
{ };
// specialized as has_member< T , void > or discarded (SFINAE)
template< class T >
struct has_member< T , decltype( T::member ) > : std::true_type
{ };
If I pass in an object without 'member', it will still default to the default template, while an object with 'member' will instantiate the specialization.
Why is that thinking flawed? I think it has something to do with the second template parameter of the primary template having a default ('class = void'). But I don't see why that matters. Why does the specialization have to use a 'void_t' to match that default parameter? Isn't the whole point of default that they can be overridden? Where can I read more about that topic of cppreference.com?