#include <iostream>
#include <iomanip>
#include <utility>
#include <type_traits>
template<typename...>
struct void_type {
using type = void;
};
template<typename ...T>
using void_t = typename void_type<T...>::type;
template<typename T, typename = void>
struct is_invokable_with_member_function_foo : std::false_type {};
template<typename T, typename ...Args>
struct is_invokable_with_member_function_foo<
T (Args...)
, void_t<decltype(std::declval<T>().foo(std::declval<Args>()...))>
> : std::true_type {};
struct A {};
struct B {
void foo();
void foo(int, double);
};
struct C {
void foo(int);
void foo(int, double) const;
};
int main() {
std::cout << std::boolalpha;
std::cout << "A::foo() -> "
<< is_invokable_with_member_function_foo<A ()>()
<< std::endl;
std::cout << "B::foo() -> "
<< is_invokable_with_member_function_foo<B ()>()
<< std::endl;
std::cout << "B::foo(int) -> "
<< is_invokable_with_member_function_foo<B (int)>()
<< std::endl;
std::cout << "B::foo(int, double) -> "
<< is_invokable_with_member_function_foo<B (int, double)>()
<< std::endl;
std::cout << "B::foo(char, int) -> "
<< is_invokable_with_member_function_foo<B (char, int)>()
<< std::endl;
std::cout << "B::foo(int, double) const -> "
<< is_invokable_with_member_function_foo<B const (int, double)>()
<< std::endl;
std::cout << "C::foo(int) -> "
<< is_invokable_with_member_function_foo<C (int)>()
<< std::endl;
std::cout << "C::foo(int, double) -> "
<< is_invokable_with_member_function_foo<C (int, double)>()
<< std::endl;
std::cout << "C::foo(int, double) const -> "
<< is_invokable_with_member_function_foo<C const (int, double)>()
<< std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aW9tYW5pcD4KI2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KCgp0ZW1wbGF0ZTx0eXBlbmFtZS4uLj4Kc3RydWN0IHZvaWRfdHlwZSB7CgogICB1c2luZyB0eXBlID0gdm9pZDsJCn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSAuLi5UPgp1c2luZyB2b2lkX3QgPSB0eXBlbmFtZSB2b2lkX3R5cGU8VC4uLj46OnR5cGU7CgoKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgPSB2b2lkPgpzdHJ1Y3QgaXNfaW52b2thYmxlX3dpdGhfbWVtYmVyX2Z1bmN0aW9uX2ZvbyA6IHN0ZDo6ZmFsc2VfdHlwZSB7fTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIC4uLkFyZ3M+CnN0cnVjdCBpc19pbnZva2FibGVfd2l0aF9tZW1iZXJfZnVuY3Rpb25fZm9vPAogICAgICBUIChBcmdzLi4uKQogICAgLCB2b2lkX3Q8ZGVjbHR5cGUoc3RkOjpkZWNsdmFsPFQ+KCkuZm9vKHN0ZDo6ZGVjbHZhbDxBcmdzPigpLi4uKSk+Cj4gOiBzdGQ6OnRydWVfdHlwZSB7fTsKCgpzdHJ1Y3QgQSB7fTsKCnN0cnVjdCBCIHsKCQogICB2b2lkIGZvbygpOwogICB2b2lkIGZvbyhpbnQsIGRvdWJsZSk7Cn07CgpzdHJ1Y3QgQyB7CiAgIHZvaWQgZm9vKGludCk7CiAgIHZvaWQgZm9vKGludCwgZG91YmxlKSBjb25zdDsKfTsKCgppbnQgbWFpbigpIHsKCXN0ZDo6Y291dCA8PCBzdGQ6OmJvb2xhbHBoYTsKCXN0ZDo6Y291dCA8PCAiQTo6Zm9vKCkgLT4gIgoJICAgICAgICAgIDw8IGlzX2ludm9rYWJsZV93aXRoX21lbWJlcl9mdW5jdGlvbl9mb288QSAoKT4oKQoJICAgICAgICAgIDw8IHN0ZDo6ZW5kbDsKCXN0ZDo6Y291dCA8PCAiQjo6Zm9vKCkgLT4gIgoJICAgICAgICAgIDw8IGlzX2ludm9rYWJsZV93aXRoX21lbWJlcl9mdW5jdGlvbl9mb288QiAoKT4oKQoJICAgICAgICAgIDw8IHN0ZDo6ZW5kbDsKCXN0ZDo6Y291dCA8PCAiQjo6Zm9vKGludCkgLT4gIgoJICAgICAgICAgIDw8IGlzX2ludm9rYWJsZV93aXRoX21lbWJlcl9mdW5jdGlvbl9mb288QiAoaW50KT4oKQoJICAgICAgICAgIDw8IHN0ZDo6ZW5kbDsKCXN0ZDo6Y291dCA8PCAiQjo6Zm9vKGludCwgZG91YmxlKSAtPiAiCgkgICAgICAgICAgPDwgaXNfaW52b2thYmxlX3dpdGhfbWVtYmVyX2Z1bmN0aW9uX2ZvbzxCIChpbnQsIGRvdWJsZSk+KCkKCSAgICAgICAgICA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgIkI6OmZvbyhjaGFyLCBpbnQpIC0+ICIKCSAgICAgICAgICA8PCBpc19pbnZva2FibGVfd2l0aF9tZW1iZXJfZnVuY3Rpb25fZm9vPEIgKGNoYXIsIGludCk+KCkKCSAgICAgICAgICA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgIkI6OmZvbyhpbnQsIGRvdWJsZSkgY29uc3QgLT4gIgoJICAgICAgICAgIDw8IGlzX2ludm9rYWJsZV93aXRoX21lbWJlcl9mdW5jdGlvbl9mb288QiBjb25zdCAoaW50LCBkb3VibGUpPigpCgkgICAgICAgICAgPDwgc3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8ICJDOjpmb28oaW50KSAtPiAiCgkgICAgICAgICAgPDwgaXNfaW52b2thYmxlX3dpdGhfbWVtYmVyX2Z1bmN0aW9uX2ZvbzxDIChpbnQpPigpCgkgICAgICAgICAgPDwgc3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8ICJDOjpmb28oaW50LCBkb3VibGUpIC0+ICIKCSAgICAgICAgICA8PCBpc19pbnZva2FibGVfd2l0aF9tZW1iZXJfZnVuY3Rpb25fZm9vPEMgKGludCwgZG91YmxlKT4oKQoJICAgICAgICAgIDw8IHN0ZDo6ZW5kbDsKCXN0ZDo6Y291dCA8PCAiQzo6Zm9vKGludCwgZG91YmxlKSBjb25zdCAtPiAiCgkgICAgICAgICAgPDwgaXNfaW52b2thYmxlX3dpdGhfbWVtYmVyX2Z1bmN0aW9uX2ZvbzxDIGNvbnN0IChpbnQsIGRvdWJsZSk+KCkKCSAgICAgICAgICA8PCBzdGQ6OmVuZGw7Cn0K