I was following Jean Guegant's SFINAE blog post, where he implements a type trait using sizeof() which checks if there is a serialize function in the class. Inside which he has this reallyHas struct which checks if serialize is just a member of the class or an actual member function, by doing this
template<typename T>
struct has_serialize {
typedef char yes[1];
typedef char no[2];
template<typename U, U u> struct reallyHas{};
template <typename C>
static yes& test(reallyHas<string (C::*)(), &C::serialize>*){}
// for const method
template<typename C>
static yes& test(reallyHas<string (C::*)() const, &C::serialize>*){}
template<typename> // variadic template
static no& test(...){} // sink hole
enum {
value = (sizeof(test<T>(0)) == sizeof(yes))
};
};
This works fine only when the test function has the signature of
template <typename C>
static yes& test(reallyHas<string (C::*)(), &C::serialize>*){}
But not when
template <typename C>
static yes& test(reallyHas<string (C::*)(), &C::serialize>){}
I don't really understand the significance of the * in the argument, In the end we are just checking if the substitution happens or not, so shouldn't it work in both the cases