There is indeed:
typedef char (&no_tag)[1];
typedef char (&yes_tag)[2];
template < typename T, void (T::*)() > struct ptmf_helper {};
template< typename T > no_tag has_member_foo_helper(...);
template< typename T >
yes_tag has_member_foo_helper(ptmf_helper<T, &T::foo>* p);
template< typename T >
struct has_member_foo
{
BOOST_STATIC_CONSTANT(bool
, value = sizeof(has_member_foo_helper<T>(0)) == sizeof(yes_tag)
);
};
struct my {};
struct her { void foo(); };
int main()
{
BOOST_STATIC_ASSERT(!has_member_foo<my>::value);
BOOST_STATIC_ASSERT(has_member_foo<her>::value);
return 0;
}
Copy-pasted from here.
Edit: Update the code, which is compliant AFAIK. Also note that you have to know the arguments of the return type of the method you're checking for.
Staffan
2010-07-08 00:44:09