There are multiple things to deal with here.
First, put the parameter pack args
at the end, otherwise the compiler doesn't know where to stop matching arguments with it (unless you specify the template arguments).
template<typename... Args>
double var_finder(double c, std::function<double (Args... args)> func, Args... args)
Second, don't name the parameter in std::function
; also just don't use std::function
, use a function pointer instead.
template<typename... Args>
double var_finder(double c, double (*func)(Args...), Args... args)
Third, make finder
static, otherwise you run into member function pointers and the syntax is more difficult to grasp (more on that later).
static double finder(double a, double b = 0)
Third, provide the optional argument for finder
. Otherwise, the parameter pack can't be deduced because it doesn't match both func
and args
.
std::cout << test.var_finder(0.1, c_test::finder, 2.0, 0.0) << std::endl;
This gives you the following.
class c_test {
public:
static double finder(double a, double b = 0) {
return a + b;
}
template<typename... Args>
double var_finder(double c, double (*func)(Args...), Args... args) {
return c * func(args...);
}
};
int main () {
c_test test;
std::cout << test.var_finder(0.1, c_test::finder, 2.0, 0.0) << std::endl;
}
Demo
If you really need finder
to not be static, then you have to deal with member function pointer syntax.
First, the parameter func
must be a member function pointer.
double (c_test::*func)(Args...) // parameter declaration
&c_test::finder // argument in call
Then, you need to pass a c_test
variable to var_finder
in order to call func
.
template<typename... Args>
double var_finder(double c, double (c_test::*func)(Args...), c_test test, Args... args) {
return c * (test.*func)(args...);
}
// [...]
std::cout << test.var_finder(0.1, &c_test::finder, test, 2.0, 0.0) << std::endl;
That gives you the following code.
class c_test {
public:
double finder(double a, double b = 0) {
return a + b;
}
template<typename... Args>
double var_finder(double c, double (c_test::*func)(Args...), c_test test, Args... args) {
return c * (test.*func)(args...);
}
};
int main () {
c_test test;
std::cout << test.var_finder(0.1, &c_test::finder, test, 2.0, 0.0) << std::endl;
}
Demo
If you want to be able to call finder
without specifying the optional parameter, then you need some intermediary, like a lambda.