#include <type_traits>
#include <iostream>
#include <iomanip>
template <class...>
using void_t = void;
template <class T, class = void>
struct has_function_f : std::false_type
{
};
template <class T>
struct has_function_f<T, void_t<decltype(std::declval<T>().f())>> : std::true_type
{
};
struct A
{
void f() {}
};
struct B
{
void g() {}
};
struct C
{
int f() { return 1; }
};
int main()
{
auto a = has_function_f<A>();
auto b = has_function_f<B>();
auto c = has_function_f<C>();
std::cout << std::boolalpha << "a: " << a.value << '\n' << "b: " << b.value << '\n' << "c: " << c.value << std::endl;
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxpb21hbmlwPgoKdGVtcGxhdGUgPGNsYXNzLi4uPgp1c2luZyB2b2lkX3QgPSB2b2lkOwoKdGVtcGxhdGUgPGNsYXNzIFQsIGNsYXNzID0gdm9pZD4Kc3RydWN0IGhhc19mdW5jdGlvbl9mIDogc3RkOjpmYWxzZV90eXBlCnsKfTsKCnRlbXBsYXRlIDxjbGFzcyBUPgpzdHJ1Y3QgaGFzX2Z1bmN0aW9uX2Y8VCwgdm9pZF90PGRlY2x0eXBlKHN0ZDo6ZGVjbHZhbDxUPigpLmYoKSk+PiA6IHN0ZDo6dHJ1ZV90eXBlCnsKfTsKCgpzdHJ1Y3QgQQp7CiAgICB2b2lkIGYoKSB7fQp9OwoKc3RydWN0IEIKewogICAgdm9pZCBnKCkge30KfTsKCnN0cnVjdCBDCnsKICAgIGludCBmKCkgeyByZXR1cm4gMTsgfQp9OwoKaW50IG1haW4oKQp7CiAgICBhdXRvIGEgPSBoYXNfZnVuY3Rpb25fZjxBPigpOwogICAgYXV0byBiID0gaGFzX2Z1bmN0aW9uX2Y8Qj4oKTsKICAgIGF1dG8gYyA9IGhhc19mdW5jdGlvbl9mPEM+KCk7CgogICAgc3RkOjpjb3V0IDw8IHN0ZDo6Ym9vbGFscGhhIDw8ICJhOiAiIDw8IGEudmFsdWUgPDwgJ1xuJyA8PCAiYjogIiA8PCBiLnZhbHVlIDw8ICdcbicgPDwgImM6ICIgPDwgYy52YWx1ZSA8PCBzdGQ6OmVuZGw7Cn0K