#include <iostream>
using namespace std;
template<typename T, typename = void_t<>>
struct HasHelloFunction : std::false_type {};
template<typename T>
struct HasHelloFunction<T, void_t<decltype(T::hello())>> : std::true_type {};
struct Works
{
static int hello() {}
};
struct Works2
{
static void hello() {}
};
struct DoesntWork
{
static int hello; // close but not callable
};
int main() {
cout << "char: " << HasHelloFunction<char>::value << endl;
cout << "Works: " << HasHelloFunction<Works>::value << endl;
cout << "Works2: " << HasHelloFunction<Works2>::value << endl;
cout << "DoesntWork: " << HasHelloFunction<DoesntWork>::value << endl;
cout << "int: " << HasHelloFunction<int>::value << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwogCnRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lID0gdm9pZF90PD4+CnN0cnVjdCBIYXNIZWxsb0Z1bmN0aW9uIDogc3RkOjpmYWxzZV90eXBlIHt9OwogCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBIYXNIZWxsb0Z1bmN0aW9uPFQsIHZvaWRfdDxkZWNsdHlwZShUOjpoZWxsbygpKT4+IDogc3RkOjp0cnVlX3R5cGUge307CiAKc3RydWN0IFdvcmtzCnsKCXN0YXRpYyBpbnQgaGVsbG8oKSB7fQp9OwogCnN0cnVjdCBXb3JrczIKewoJc3RhdGljIHZvaWQgaGVsbG8oKSB7fQp9OwogCnN0cnVjdCBEb2VzbnRXb3JrCnsKICAgIHN0YXRpYyBpbnQgaGVsbG87IC8vIGNsb3NlIGJ1dCBub3QgY2FsbGFibGUKfTsKIAppbnQgbWFpbigpIHsKIAoJY291dCA8PCAiY2hhcjogIiA8PCBIYXNIZWxsb0Z1bmN0aW9uPGNoYXI+Ojp2YWx1ZSA8PCBlbmRsOwoJY291dCA8PCAiV29ya3M6ICIgPDwgSGFzSGVsbG9GdW5jdGlvbjxXb3Jrcz46OnZhbHVlIDw8IGVuZGw7Cgljb3V0IDw8ICJXb3JrczI6ICIgPDwgSGFzSGVsbG9GdW5jdGlvbjxXb3JrczI+Ojp2YWx1ZSA8PCBlbmRsOwoJY291dCA8PCAiRG9lc250V29yazogIiA8PCBIYXNIZWxsb0Z1bmN0aW9uPERvZXNudFdvcms+Ojp2YWx1ZSA8PCBlbmRsOwoJY291dCA8PCAiaW50OiAiIDw8IEhhc0hlbGxvRnVuY3Rpb248aW50Pjo6dmFsdWUgPDwgZW5kbDsKIAoJcmV0dXJuIDA7Cn0=