По мотивам
SFINAE2Автор: Roman Odaisky
Дата: 14.06.06
и
SFINAE3Автор: remark
Дата: 18.06.06
. Основная проблема в приведенных решениях, что они не компилируются под студией.
Основным отличием от
здесьАвтор: gid_vvp
Дата: 16.02.07
является то, что не требуется явно задавать тип метода.
template <typename Type>
class has_member
{
class yes { char m;};
class no { yes m[2];};
struct BaseMixin
{
void func(){}
};
struct Base : public Type, public BaseMixin {};
template <typename T, T t> class Helper{};
//наличия метода в Type приводит к ambiguous в соответствии с 10.2.2
//в случае отсутствия метода &Base::func имеет тип void (BaseMixin::*)()
template <typename U>
static no deduce(U*, Helper<void (BaseMixin::*)(), &U::func>* = 0);
static yes deduce(...);
public:
static const bool result = sizeof(yes) == sizeof(deduce((Base*)(0)));
};
struct With
{
void func(int, long) const{}
};
struct WithTemplate
{
template <typename T, typename U>
void func(T, U){}
};
struct Without
{
};
int main()
{
int check1[has_member<With>::result? 1 : -1];
int check2[has_member<WithTemplate>::result? 1 : -1];
int check3[!has_member<Without>::result? 1 : -1];
return 0;
}
Компилировал c VC 7.1, VC 8.0, Comeau C/C++ online