I want to make a simple logger which automatically runs a function and returns its value.
The class is defined as:
template <typename R, typename... Args>
class Logger3
{
Logger3(function<R(Args...)> func,
const string& name):
func{func},
name{name}
{}
R operator() (Args ...args)
{
cout << "Entering " << name << endl;
R result = func(args...);
cout << "Exiting " << name << endl;
return result;
}
function<R(Args...)> func;
string name;
};
I want to pass the following simple add
function to the logger:
int add(int a, int b)
{
cout<<"Add two value"<<endl;
return a+b;
}
By calling it this way:
auto caller = Logger3<int(int,int)>(add,"test");
However, it generates the following errors:
error: function returning a function
133 | Logger3(function<R(Args...)> func,
| ^~~~~~~
decorator.h:138:7: error: function returning a function
138 | R operator() (Args ...args)
| ^~~~~~~~
decorator.h:145:26: error: function returning a function
145 | function<R(Args...)> func;
Args
inoperator()
is from the primary class template and not from a function template. This means thatArgs...
is not a forwarding reference. If the function is defined to have arguments taken by-value, then there will always be a copy of the argument when callingoperator()
. You can avoid copies even ifArgs...
are by value ifoperator()
was itself a variadic template using forwarding references: compiler-explorer.com/z/6GfGjbnYP. – Zach