简体   繁体   中英

Why SFINAE trick doesn't work for non-class type when tried for class member pointer?

With curiosity, I was trying an alternate implementation of is_class construct using the sizeof() trick. Following 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)) };
};

Problem is when I instantiate is_class<int> , it gives compile error:

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

Now, my question is, if int T::* is not applicable for int (or void* etc.) then why doesn't substitution fail for yes check . Shouldn't compiler select the no check ?

yes and no are not templates, SFINAE cannot possibly apply 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)) };
};

Now SFINAE can kick in.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM