#include <iostream>
struct A { void reset() { std::cout << "reset A" << std::endl; } };
struct B { void reset() { std::cout << "reset B" << std::endl; } };
struct X :public A{};
template <typename T, typename R, typename BT>
typename std::enable_if<std::is_base_of<BT, T>::value, R>::type
call_if_possible(T & obj, R(BT::*mf)())
{
return (obj.*mf)();
}
template <typename T, typename R, typename BT>
typename std::enable_if<!std::is_base_of<BT, T>::value, R>::type
call_if_possible(T & obj, R(BT::*mf)()) { }
int main()
{
X x;
call_if_possible(x, &A::reset);
call_if_possible(x, &B::reset);
}
CiNpbmNsdWRlIDxpb3N0cmVhbT4KCnN0cnVjdCBBICAgIHsgdm9pZCByZXNldCgpIHsgc3RkOjpjb3V0IDw8ICJyZXNldCBBIiA8PCBzdGQ6OmVuZGw7IH0gfTsKc3RydWN0IEIgICAgeyB2b2lkIHJlc2V0KCkgeyBzdGQ6OmNvdXQgPDwgInJlc2V0IEIiIDw8IHN0ZDo6ZW5kbDsgfSB9OwoKc3RydWN0IFggOnB1YmxpYyBBe307Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgUiwgdHlwZW5hbWUgQlQ+CnR5cGVuYW1lIHN0ZDo6ZW5hYmxlX2lmPHN0ZDo6aXNfYmFzZV9vZjxCVCwgVD46OnZhbHVlLCBSPjo6dHlwZQpjYWxsX2lmX3Bvc3NpYmxlKFQgJiBvYmosIFIoQlQ6OiptZikoKSkKewoJcmV0dXJuIChvYmouKm1mKSgpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgUiwgdHlwZW5hbWUgQlQ+CnR5cGVuYW1lIHN0ZDo6ZW5hYmxlX2lmPCFzdGQ6OmlzX2Jhc2Vfb2Y8QlQsIFQ+Ojp2YWx1ZSwgUj46OnR5cGUKY2FsbF9pZl9wb3NzaWJsZShUICYgb2JqLCBSKEJUOjoqbWYpKCkpIHsgfQoKaW50IG1haW4oKQp7CglYIHg7CgoJY2FsbF9pZl9wb3NzaWJsZSh4LCAmQTo6cmVzZXQpOwoJY2FsbF9pZl9wb3NzaWJsZSh4LCAmQjo6cmVzZXQpOwp9Cg==