#include <iostream>
using namespace std;
class unsafe_func
{
public:
template<class F>
explicit unsafe_func(F f) : pd(new detail_impl<F>(f)) {
}
~unsafe_func() {
delete pd;
}
template<class R, class ... Args>
R call(Args ... args) const {
return static_cast< detail_impl<R(*)(Args ...)>* >(pd)->f_(args...);
}
private:
unsafe_func(unsafe_func const &);
unsafe_func& operator=(unsafe_func const &);
struct detail
{
virtual ~detail() {}
};
template<class F>
struct detail_impl : detail
{
F f_;
detail_impl(F f) : f_(f) {
}
};
detail* pd;
};
struct helloworld
{
void funcA() const {
std::cout << "void helloworld::funcA()" << std::endl;
}
int funcB(int, int) const {
std::cout << "int helloworld::funcB(int, int)" << std::endl;
return 0;
}
};
int main() {
unsafe_func pf(&helloworld::funcA);
unsafe_func pf2(&helloworld::funcB);
helloworld *p = 0;
pf.call<void>(p);
pf2.call<int>(p, 0, 0);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY2xhc3MgdW5zYWZlX2Z1bmMKewpwdWJsaWM6Cgl0ZW1wbGF0ZTxjbGFzcyBGPgoJZXhwbGljaXQgdW5zYWZlX2Z1bmMoRiBmKSA6IHBkKG5ldyBkZXRhaWxfaW1wbDxGPihmKSkgewoJfQoKCX51bnNhZmVfZnVuYygpIHsKCQlkZWxldGUgcGQ7Cgl9CgoJdGVtcGxhdGU8Y2xhc3MgUiwgY2xhc3MgLi4uIEFyZ3M+CglSIGNhbGwoQXJncyAuLi4gYXJncykgY29uc3QgewoJCXJldHVybiBzdGF0aWNfY2FzdDwgZGV0YWlsX2ltcGw8UigqKShBcmdzIC4uLik+KiA+KHBkKS0+Zl8oYXJncy4uLik7Cgl9Cgpwcml2YXRlOgoJdW5zYWZlX2Z1bmModW5zYWZlX2Z1bmMgY29uc3QgJik7Cgl1bnNhZmVfZnVuYyYgb3BlcmF0b3I9KHVuc2FmZV9mdW5jIGNvbnN0ICYpOwoKCXN0cnVjdCBkZXRhaWwKCXsKCQl2aXJ0dWFsIH5kZXRhaWwoKSB7fQoJfTsKCgl0ZW1wbGF0ZTxjbGFzcyBGPgoJc3RydWN0IGRldGFpbF9pbXBsIDogZGV0YWlsCgl7CgkJRiBmXzsKCQlkZXRhaWxfaW1wbChGIGYpIDogZl8oZikgewoJCX0KCX07CgoJZGV0YWlsKiBwZDsKfTsKCnN0cnVjdCBoZWxsb3dvcmxkCnsKCXZvaWQgZnVuY0EoKSBjb25zdCB7CgkJc3RkOjpjb3V0IDw8ICJ2b2lkIGhlbGxvd29ybGQ6OmZ1bmNBKCkiIDw8IHN0ZDo6ZW5kbDsKCX0KCglpbnQgZnVuY0IoaW50LCBpbnQpIGNvbnN0IHsKCQlzdGQ6OmNvdXQgPDwgImludCBoZWxsb3dvcmxkOjpmdW5jQihpbnQsIGludCkiIDw8IHN0ZDo6ZW5kbDsKCQlyZXR1cm4gMDsKCX0KfTsKCmludCBtYWluKCkgewoJdW5zYWZlX2Z1bmMgcGYoJmhlbGxvd29ybGQ6OmZ1bmNBKTsKCXVuc2FmZV9mdW5jIHBmMigmaGVsbG93b3JsZDo6ZnVuY0IpOwoKCWhlbGxvd29ybGQgKnAgPSAwOwoKCXBmLmNhbGw8dm9pZD4ocCk7CglwZjIuY2FsbDxpbnQ+KHAsIDAsIDApOwoKCXJldHVybiAwOwp9