Why doesn't the SFINAE trick work for a non-class type when trying to pointer to a class member?

With curiosity, I tried an alternative implementation of is_class using the sizeof() trick. Below is the code:

 template<typename T> struct is_class { typedef char (&yes)[7]; typedef char (&no)[3]; static yes check (int T::*); static no check (...); enum { value = (sizeof(check(0)) == sizeof(yes)) }; }; 

The problem is that when I instantiate is_class<int> , it gives a compilation error:

 error: creating pointer to member of non-class type 'int' 

Now, my question is: if int T::* not applicable for int (or void* , etc.), then why does not perform a replacement for yes check . Should the compiler choose no check ?

+6
source share
1 answer

yes and no are not templates, SFINAE cannot be applied to them. You need to do this:

 template<typename T> struct is_class { typedef char (&yes)[7]; typedef char (&no)[3]; template <typename U> static yes check (int U::*); template <typename> static no check (...); enum { value = (sizeof(check<T>(0)) == sizeof(yes)) }; }; 

SFINAE can now take a hit.

+10
source

Source: https://habr.com/ru/post/891909/


All Articles