只需调用成员函数并丢弃 SFINAE 上下文中的结果。如果成功,则该方法存在。如果失败,则方法不会。
// not needed in C++1y
template<class T,class V=void>using enable_if_t=typename enable_if<T,V>::type;
// If the other tests fail, the type T does not have a method `foo` of
// signature Sig. The class=void parameter is an implementation detail
// that in an industrial quality implementation we would hide in a helper
// template type.
template<class T,class Sig,class=void>struct has_foo:std::false_type{};
// For R(Args...), we attempt to invoke `T::foo` with (Args...), then check
// if we can assign the return value to a variable of type R.
template<class T,class R,class...Args>
struct has_foo<T,R(Args...),
enable_if_t< // std:: in C++1y
std::is_convertible<
decltype( T::foo( std::declval<Args>()... ) ),
R
>::value
&& !std::is_same<R, void>::value
>
>: std::true_type {};
// for `void` return value, we only care if the function can be invoked,
// no convertible test required:
template<class T,class...Args>
struct has_foo<T,void(Args...),
decltype( void(T::foo( std::declval<Args>()... ) ) )
>: std::true_type {};
使用:
has_foo< bar, int(int) >::value
它检查int r = T::foo( 7 ) 是否是一个有效的表达式,而不是精确的签名匹配。