#include <type_traits>
template <typename C, typename F, typename = void>
struct is_call_possible : public std::false_type {};
template <typename C, typename R, typename... A>
struct is_call_possible<C, R(A...),
typename std::enable_if<
std::is_same<R, void>::value ||
std::is_convertible<decltype(
std::declval<C>().operator()(std::declval<A>()...)
), R>::value
>::type
> : public std::true_type {};
// Demo
#include <string>
struct Foo
{
void operator()(double) const {}
void operator()(std::string) const {}
};
struct Bar : Foo
{
int operator()(int)
{
return 0;
}
};
static_assert(is_call_possible<Foo, void(double)>::value, "?");
static_assert(is_call_possible<Foo, void(int)>::value, "?");
static_assert(is_call_possible<Foo, void(const char*)>::value, "?");
static_assert(!is_call_possible<Foo, void(void*)>::value, "?");
static_assert(is_call_possible<Bar, void(double)>::value, "?");
static_assert(is_call_possible<Bar, void(int)>::value, "?");
static_assert(!is_call_possible<Bar, void(const char*)>::value, "?");
static_assert(!is_call_possible<Bar, void(void*)>::value, "?");
static_assert(is_call_possible<Bar, int(int)>::value, "?");
static_assert(is_call_possible<Bar, double(int)>::value, "?");
static_assert(!is_call_possible<Bar, std::string(int)>::value, "?");
static_assert(!is_call_possible<Bar, void()>::value, "?");
int main() {}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKdGVtcGxhdGUgPHR5cGVuYW1lIEMsIHR5cGVuYW1lIEYsIHR5cGVuYW1lID0gdm9pZD4Kc3RydWN0IGlzX2NhbGxfcG9zc2libGUgOiBwdWJsaWMgc3RkOjpmYWxzZV90eXBlIHt9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIEMsIHR5cGVuYW1lIFIsIHR5cGVuYW1lLi4uIEE+CnN0cnVjdCBpc19jYWxsX3Bvc3NpYmxlPEMsIFIoQS4uLiksCiAgICB0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjwKICAgICAgICBzdGQ6OmlzX3NhbWU8Uiwgdm9pZD46OnZhbHVlIHx8CiAgICAgICAgc3RkOjppc19jb252ZXJ0aWJsZTxkZWNsdHlwZSgKICAgICAgICAgICAgc3RkOjpkZWNsdmFsPEM+KCkub3BlcmF0b3IoKShzdGQ6OmRlY2x2YWw8QT4oKS4uLikKICAgICAgICApLCBSPjo6dmFsdWUKICAgID46OnR5cGUKPiA6IHB1YmxpYyBzdGQ6OnRydWVfdHlwZSB7fTsKCi8vIERlbW8KCiNpbmNsdWRlIDxzdHJpbmc+CgpzdHJ1Y3QgRm9vCnsKICAgdm9pZCBvcGVyYXRvcigpKGRvdWJsZSkgY29uc3Qge30KICAgdm9pZCBvcGVyYXRvcigpKHN0ZDo6c3RyaW5nKSBjb25zdCB7fQp9OwoKc3RydWN0IEJhciA6IEZvbwp7CiAgIGludCBvcGVyYXRvcigpKGludCkKICAgewogICAgIHJldHVybiAwOwogICB9Cn07CgpzdGF0aWNfYXNzZXJ0KGlzX2NhbGxfcG9zc2libGU8Rm9vLCB2b2lkKGRvdWJsZSk+Ojp2YWx1ZSwgIj8iKTsKc3RhdGljX2Fzc2VydChpc19jYWxsX3Bvc3NpYmxlPEZvbywgdm9pZChpbnQpPjo6dmFsdWUsICI/Iik7CnN0YXRpY19hc3NlcnQoaXNfY2FsbF9wb3NzaWJsZTxGb28sIHZvaWQoY29uc3QgY2hhciopPjo6dmFsdWUsICI/Iik7CnN0YXRpY19hc3NlcnQoIWlzX2NhbGxfcG9zc2libGU8Rm9vLCB2b2lkKHZvaWQqKT46OnZhbHVlLCAiPyIpOwpzdGF0aWNfYXNzZXJ0KGlzX2NhbGxfcG9zc2libGU8QmFyLCB2b2lkKGRvdWJsZSk+Ojp2YWx1ZSwgIj8iKTsKc3RhdGljX2Fzc2VydChpc19jYWxsX3Bvc3NpYmxlPEJhciwgdm9pZChpbnQpPjo6dmFsdWUsICI/Iik7CnN0YXRpY19hc3NlcnQoIWlzX2NhbGxfcG9zc2libGU8QmFyLCB2b2lkKGNvbnN0IGNoYXIqKT46OnZhbHVlLCAiPyIpOwpzdGF0aWNfYXNzZXJ0KCFpc19jYWxsX3Bvc3NpYmxlPEJhciwgdm9pZCh2b2lkKik+Ojp2YWx1ZSwgIj8iKTsKc3RhdGljX2Fzc2VydChpc19jYWxsX3Bvc3NpYmxlPEJhciwgaW50KGludCk+Ojp2YWx1ZSwgIj8iKTsKCnN0YXRpY19hc3NlcnQoaXNfY2FsbF9wb3NzaWJsZTxCYXIsIGRvdWJsZShpbnQpPjo6dmFsdWUsICI/Iik7CnN0YXRpY19hc3NlcnQoIWlzX2NhbGxfcG9zc2libGU8QmFyLCBzdGQ6OnN0cmluZyhpbnQpPjo6dmFsdWUsICI/Iik7CnN0YXRpY19hc3NlcnQoIWlzX2NhbGxfcG9zc2libGU8QmFyLCB2b2lkKCk+Ojp2YWx1ZSwgIj8iKTsKCmludCBtYWluKCkge30KCg==