Reputation: 2096
#include <iostream>
#include <string>
template<typename Func>
class FuncWrapper {
Func func;
std::string name;
public:
FuncWrapper(Func func, std::string name) : func(func), name(std::move(name)) {}
template<typename ...Args>
auto operator()(Args ...args) {
std::cout << "Entering " + name + '\n';
auto ret = func(args...);
std::cout << "Exiting " + name + "\n\n";
return ret;
}
};
template<typename Func>
auto makeFuncWrapper(Func func, std::string name) {
return FuncWrapper<Func>(func, name);
}
int main() {
auto helloWorld = []() { std::cout << "Hello World\n"; };
auto addTwoNums = [](int a, int b) { std::cout << "Adding numbers...\n"; return a + b; };
// makeFuncWrapper(helloWorld, "helloWorld")(); // error: 'void ret' has incomplete type.
std::cout << makeFuncWrapper(addTwoNums, "addTwoNums")(4, 5) << '\n';
}
This class FuncWrapper
works fine and adds an additional functionality to the passed function, until the passed function is a function that returns void
. I get an error that the type of ret
is incomplete. Is there any other way to make it work even with functions with return type of void
? I know that I can't have a void
variable, but here, the only purpose of ret
is to be returned after the function is done and it's not gonna be used in a wrong way. Is there a solution or some workaround to make it work? Any better way of implementing a function wrapper that wraps any function?
Upvotes: 0
Views: 1110
Reputation: 217085
You might use Raii:
template<typename ...Args>
auto operator()(Args ...args) {
struct EndScope {
std::string& name;
~EndScope() { std::cout << "Exiting " + name + "\n\n"; }
} endScope(name);
std::cout << "Entering " + name + '\n';
return func(args...);
}
You might go further to handle exception with std::uncaught_exceptions
See raii-way-to-get-errors-that-are-caught-during-destruction
Upvotes: -1