#include <iostream>
#include <iomanip>
#include <utility>
#include <type_traits>
using namespace std;
struct has
{
void operator()(int const&);
};
struct hasNot1
{
void operator()(int);
};
struct hasNot2
{
void operator()();
};
struct hasNot3
{
void operator()(float);
};
struct hasNot4
{
};
template<typename T, typename EDT>
struct is_callable_oper
{
private:
typedef char(&yes)[1];
typedef char(&no)[2];
template <typename U, void (U::*)(EDT const &)> struct
Check;
template<typename>
static yes test(...);
template <typename U>
static no
test(Check<U, &U::operator()>*);
public:
static constexpr bool value = sizeof(test<T>(0))
== sizeof(yes);
};
int main() {
cout << boolalpha << is_callable_oper<has, int&>::value << " "
<< is_callable_oper<has, int>::value << " "
<< is_callable_oper<hasNot1, int&>::value << " "
<< is_callable_oper<hasNot2, int&>::value << " "
<< is_callable_oper<hasNot3, int&>::value << " "
<< is_callable_oper<hasNot4, int&>::value << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aW9tYW5pcD4KI2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgpzdHJ1Y3QgaGFzCnsKCXZvaWQgb3BlcmF0b3IoKShpbnQgY29uc3QmKTsJCn07CgpzdHJ1Y3QgaGFzTm90MQp7Cgl2b2lkIG9wZXJhdG9yKCkoaW50KTsJCn07CgpzdHJ1Y3QgaGFzTm90Mgp7Cgl2b2lkIG9wZXJhdG9yKCkoKTsJCn07CgpzdHJ1Y3QgaGFzTm90Mwp7Cgl2b2lkIG9wZXJhdG9yKCkoZmxvYXQpOwkKfTsKCnN0cnVjdCBoYXNOb3Q0CnsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEVEVD4Kc3RydWN0IGlzX2NhbGxhYmxlX29wZXIKewogICAgICBwcml2YXRlOgogICAgICAgICAgICAgICAgICAgIHR5cGVkZWYgY2hhcigmeWVzKVsxXTsKICAgICAgICAgICAgICAgICAgICB0eXBlZGVmIGNoYXIoJm5vKVsyXTsKCiAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGUgPHR5cGVuYW1lIFUsIHZvaWQgKFU6OiopKEVEVCBjb25zdCAmKT4gc3RydWN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENoZWNrOwogICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlPHR5cGVuYW1lPgogICAgICAgICAgICAgICAgICAgIHN0YXRpYyB5ZXMgdGVzdCguLi4pOwoKICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVT4KICAgICAgICAgICAgICAgICAgICBzdGF0aWMgbm8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlc3QoQ2hlY2s8VSwgJlU6Om9wZXJhdG9yKCk+Kik7CgogICAgICAgICAgICAgICAgcHVibGljOgogICAgICAgICAgICAgICAgICAgIHN0YXRpYyBjb25zdGV4cHIgYm9vbCB2YWx1ZSA9IHNpemVvZih0ZXN0PFQ+KDApKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT0gc2l6ZW9mKHllcyk7Cn07CgppbnQgbWFpbigpIHsKCWNvdXQgPDwgYm9vbGFscGhhIDw8IGlzX2NhbGxhYmxlX29wZXI8aGFzLCBpbnQmPjo6dmFsdWUgPDwgIiAiIAoJCSA8PCBpc19jYWxsYWJsZV9vcGVyPGhhcywgaW50Pjo6dmFsdWUgPDwgIiAiCgkJIDw8IGlzX2NhbGxhYmxlX29wZXI8aGFzTm90MSwgaW50Jj46OnZhbHVlIDw8ICIgIgoJCSA8PCBpc19jYWxsYWJsZV9vcGVyPGhhc05vdDIsIGludCY+Ojp2YWx1ZSA8PCAiICIKCQkgPDwgaXNfY2FsbGFibGVfb3BlcjxoYXNOb3QzLCBpbnQmPjo6dmFsdWUgPDwgIiAiCgkJIDw8IGlzX2NhbGxhYmxlX29wZXI8aGFzTm90NCwgaW50Jj46OnZhbHVlIDw8IGVuZGw7CglyZXR1cm4gMDsKfQ==