#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.
}