// Example program
#include <iostream>
#include <string>
namespace mpl {
template<typename ...>
struct void_type
{
using type = void;
};
template<typename ...T>
using void_t = typename void_type<T...>::type;
} // namespace mpl
#define CAN_CALL_METHOD(NAME) \
namespace internal { \
template<typename T, typename ...Args> \
using result_of_call_method_##NAME = decltype( \
std::declval<T>().NAME(std::declval<Args>()...)); \
} \
template<typename T, typename Signature, typename = void> \
struct can_call_method_##NAME: std::false_type \
{}; \
template<typename T, typename ...Args> \
struct can_call_method_##NAME<T, void(Args...), \
mpl::void_t<internal::result_of_call_method_##NAME<T, Args...>> \
>: std::true_type \
{}; \
template<typename T, typename R, typename ...Args> \
struct can_call_method_##NAME<T, R(Args...), \
typename std::enable_if<!std::is_void<R>::value && \
std::is_convertible<internal::result_of_call_method_##NAME<T, Args...>, R \
>::value \
>::type \
>: std::true_type \
{};
CAN_CALL_METHOD(hello);
struct Foo {
template <typename T>
void hello(T&) {}
};
struct Foo1 {
};
int main()
{
std::cout << std::boolalpha;
std::cout << can_call_method_hello<Foo, void(int&)>::value << std::endl;
std::cout << can_call_method_hello<Foo1, void(int&)>::value << std::endl;
}
Ly8gRXhhbXBsZSBwcm9ncmFtCiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHN0cmluZz4KCm5hbWVzcGFjZSBtcGwgewoKdGVtcGxhdGU8dHlwZW5hbWUgLi4uPgpzdHJ1Y3Qgdm9pZF90eXBlCnsKICAgIHVzaW5nIHR5cGUgPSB2b2lkOwp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgLi4uVD4KdXNpbmcgdm9pZF90ID0gdHlwZW5hbWUgdm9pZF90eXBlPFQuLi4+Ojp0eXBlOwoKfSAvLyBuYW1lc3BhY2UgbXBsCgojZGVmaW5lIENBTl9DQUxMX01FVEhPRChOQU1FKSBcCm5hbWVzcGFjZSBpbnRlcm5hbCB7IFwKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgLi4uQXJncz4gXAp1c2luZyByZXN1bHRfb2ZfY2FsbF9tZXRob2RfIyNOQU1FID0gZGVjbHR5cGUoIFwKICAgIHN0ZDo6ZGVjbHZhbDxUPigpLk5BTUUoc3RkOjpkZWNsdmFsPEFyZ3M+KCkuLi4pKTsgXAp9IFwKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgU2lnbmF0dXJlLCB0eXBlbmFtZSA9IHZvaWQ+IFwKc3RydWN0IGNhbl9jYWxsX21ldGhvZF8jI05BTUU6IHN0ZDo6ZmFsc2VfdHlwZSBcCnt9OyBcCnRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIC4uLkFyZ3M+IFwKc3RydWN0IGNhbl9jYWxsX21ldGhvZF8jI05BTUU8VCwgdm9pZChBcmdzLi4uKSwgXAogICAgbXBsOjp2b2lkX3Q8aW50ZXJuYWw6OnJlc3VsdF9vZl9jYWxsX21ldGhvZF8jI05BTUU8VCwgQXJncy4uLj4+IFwKICAgID46IHN0ZDo6dHJ1ZV90eXBlIFwKe307IFwKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgUiwgdHlwZW5hbWUgLi4uQXJncz4gXApzdHJ1Y3QgY2FuX2NhbGxfbWV0aG9kXyMjTkFNRTxULCBSKEFyZ3MuLi4pLCBcCiAgICB0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjwhc3RkOjppc192b2lkPFI+Ojp2YWx1ZSAmJiBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjppc19jb252ZXJ0aWJsZTxpbnRlcm5hbDo6cmVzdWx0X29mX2NhbGxfbWV0aG9kXyMjTkFNRTxULCBBcmdzLi4uPiwgUiBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID46OnZhbHVlIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgPjo6dHlwZSBcCiAgICA+OiBzdGQ6OnRydWVfdHlwZSBcCnt9OyAKCkNBTl9DQUxMX01FVEhPRChoZWxsbyk7CgpzdHJ1Y3QgRm9vIHsKICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KICB2b2lkIGhlbGxvKFQmKSB7fQp9OwoKc3RydWN0IEZvbzEgewp9OwoKaW50IG1haW4oKQp7CiAgc3RkOjpjb3V0IDw8IHN0ZDo6Ym9vbGFscGhhOwogIHN0ZDo6Y291dCA8PCBjYW5fY2FsbF9tZXRob2RfaGVsbG88Rm9vLCB2b2lkKGludCYpPjo6dmFsdWUgPDwgc3RkOjplbmRsOwogIHN0ZDo6Y291dCA8PCBjYW5fY2FsbF9tZXRob2RfaGVsbG88Rm9vMSwgdm9pZChpbnQmKT46OnZhbHVlIDw8IHN0ZDo6ZW5kbDsKfQo=