#include <iostream>
#include <utility>
void foo() {
std::cout << "void foo()\n";
}
int bar(int u, char* c_str) {
std::cout << "int bar(" << u << ", \"" << c_str << "\")\n";
return u;
}
template<typename T>
class WrapFuncObj;
template<typename T, typename... Args>
class WrapFuncObj<T(Args...)> {
T (*f)(Args...);
public:
WrapFuncObj(T (*t)(Args...)) {
f = t;
}
T operator()(Args&&... args) {
if(f != nullptr) {
return (*f)(std::forward<Args>(args)...);
} else {
return T();
}
}
};
int main() {
WrapFuncObj<void()> wrap_foo(&foo);
wrap_foo();
WrapFuncObj<int(int, char*)> wrap_bar(&bar);
wrap_bar(0, "test");
WrapFuncObj<void()> wrap_null(nullptr);
wrap_null(); // prints nothing.
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dXRpbGl0eT4KCnZvaWQgZm9vKCkgewoJc3RkOjpjb3V0IDw8ICJ2b2lkIGZvbygpXG4iOwp9CgogaW50IGJhcihpbnQgdSwgY2hhciogY19zdHIpIHsKIAlzdGQ6OmNvdXQgPDwgImludCBiYXIoIiA8PCB1IDw8ICIsIFwiIiA8PCBjX3N0ciA8PCAiXCIpXG4iOwogCXJldHVybiB1OwogfQoKdGVtcGxhdGU8dHlwZW5hbWUgVD4KY2xhc3MgV3JhcEZ1bmNPYmo7Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBULCAgdHlwZW5hbWUuLi4gQXJncz4KY2xhc3MgV3JhcEZ1bmNPYmo8VChBcmdzLi4uKT4gewogICAgVCAoKmYpKEFyZ3MuLi4pOwpwdWJsaWM6CiAgICBXcmFwRnVuY09iaihUICgqdCkoQXJncy4uLikpIHsKICAgICAgICBmID0gdDsKICAgIH0KCiAgICBUIG9wZXJhdG9yKCkoQXJncyYmLi4uIGFyZ3MpIHsKICAgICAgICBpZihmICE9IG51bGxwdHIpIHsKICAgICAgICAgICAgcmV0dXJuICgqZikoc3RkOjpmb3J3YXJkPEFyZ3M+KGFyZ3MpLi4uKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gVCgpOwogICAgICAgIH0KICAgIH0KfTsKCmludCBtYWluKCkgewoJV3JhcEZ1bmNPYmo8dm9pZCgpPiB3cmFwX2ZvbygmZm9vKTsKCXdyYXBfZm9vKCk7CgkKCVdyYXBGdW5jT2JqPGludChpbnQsIGNoYXIqKT4gd3JhcF9iYXIoJmJhcik7IAoJd3JhcF9iYXIoMCwgInRlc3QiKTsKCQoJV3JhcEZ1bmNPYmo8dm9pZCgpPiB3cmFwX251bGwobnVsbHB0cik7Cgl3cmFwX251bGwoKTsgLy8gcHJpbnRzIG5vdGhpbmcuCn0=