#include <iostream>
using namespace std;
struct Action
{
template <typename T>
static bool func_real(T a){return func(a, special_());}
private:
struct general_ {};
struct special_ : general_ {};
template<typename> struct bool_ { typedef bool type; };
template<typename S, typename bool_<decltype(std::declval<S>().Y())>::type = 0>
static bool func(S a, special_) {
cout<<"Y() exists"<<endl;
if(a.X()){
return a.Y();
}
return false;
}
template<typename S>
static bool func(S a, general_) {
cout<<"Y() does not exist"<<endl;
return false;
}
};
struct Has{
bool X(){return true;}
bool Y(){return true;}
};
struct Has2{
bool X(){return true;}
bool Y(){return false;}
};
struct HasNo{
bool X(){return false;}
};
int main() {
Has has;
Has2 has2;
HasNo no;
cout<< Action::func_real<Has>(has) <<endl;
cout<< Action::func_real<Has2>(has2) <<endl;
cout<< Action::func_real<HasNo>(no) <<endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKc3RydWN0IEFjdGlvbgp7Cgl0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KCXN0YXRpYyBib29sIGZ1bmNfcmVhbChUIGEpe3JldHVybiBmdW5jKGEsIHNwZWNpYWxfKCkpO30KCQpwcml2YXRlOgoKICAgIHN0cnVjdCBnZW5lcmFsXyB7fTsKICAgIHN0cnVjdCBzcGVjaWFsXyA6IGdlbmVyYWxfIHt9OwogICAgdGVtcGxhdGU8dHlwZW5hbWU+IHN0cnVjdCBib29sXyB7IHR5cGVkZWYgYm9vbCB0eXBlOyB9OwoKICAgIHRlbXBsYXRlPHR5cGVuYW1lIFMsIHR5cGVuYW1lIGJvb2xfPGRlY2x0eXBlKHN0ZDo6ZGVjbHZhbDxTPigpLlkoKSk+Ojp0eXBlID0gMD4KICAgIHN0YXRpYyBib29sIGZ1bmMoUyBhLCBzcGVjaWFsXykgewogICAgCWNvdXQ8PCJZKCkgZXhpc3RzIjw8ZW5kbDsKICAgIAlpZihhLlgoKSl7CiAgICAJCXJldHVybiBhLlkoKTsKICAgIAl9CiAgCQlyZXR1cm4gZmFsc2U7CiAgICB9CgogICAgdGVtcGxhdGU8dHlwZW5hbWUgUz4KICAgIHN0YXRpYyBib29sIGZ1bmMoUyBhLCBnZW5lcmFsXykgewogICAgICAgIGNvdXQ8PCJZKCkgZG9lcyBub3QgZXhpc3QiPDxlbmRsOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfTsKCgpzdHJ1Y3QgSGFzewoJYm9vbCBYKCl7cmV0dXJuIHRydWU7fQoJYm9vbCBZKCl7cmV0dXJuIHRydWU7fQp9OwoKc3RydWN0IEhhczJ7Cglib29sIFgoKXtyZXR1cm4gdHJ1ZTt9Cglib29sIFkoKXtyZXR1cm4gZmFsc2U7fQp9OwoKc3RydWN0IEhhc05vewoJYm9vbCBYKCl7cmV0dXJuIGZhbHNlO30KfTsKCmludCBtYWluKCkgewoJSGFzIGhhczsKCUhhczIgaGFzMjsKCUhhc05vIG5vOwoJY291dDw8IEFjdGlvbjo6ZnVuY19yZWFsPEhhcz4oaGFzKSA8PGVuZGw7Cgljb3V0PDwgQWN0aW9uOjpmdW5jX3JlYWw8SGFzMj4oaGFzMikgPDxlbmRsOwoJY291dDw8IEFjdGlvbjo6ZnVuY19yZWFsPEhhc05vPihubykgPDxlbmRsOwoJcmV0dXJuIDA7Cn0=