I have a function defined this way:
template <size_t SIZE>
double MyFun(std::function<double(std::array<double,SIZE>&)> f, std::array<double,SIZE> &x, std::array<double,SIZE> &y){
instructions;
}
and another function, which should be the argument of the previous, defined like this:
double MyFun2(std::array<double,3> &var){
instructions;
}
If I try to call "MyFun" like this:
double something;
std::array<double,3> var = {...};
std::array<double,3> var2 = {...};
something = MyFun(MyFun2, var, var2);
I get this error:
error: no matching function for call to ‘MyFun(double (&)(std::array<double, 3>&), std::array<double, 3>&, std::array<double, 3>&)’
note: template argument deduction/substitution failed:
note: mismatched types ‘std::function<double(std::array<double, SIZE>&)>’ and ‘double (*)(std::array<double, 3>&)’
Moreover, if I try to store "MyFun2" in a variable with "auto"
auto function = MyFun2;
the type given to "function" is:
double (*function)(std::array<double, 3UL> &var)
and I can't use "function" as a parameter for MyFun aswell. The only solution I've found is to somewhat cast "MyFun2" in the right type by specifying it:
double something;
std::array<double,3> var = {...};
std::array<double,3> var2 = {...};
std::function<double(std::array<double,3>&)> function = MyFun2;
something = MyFun(function, var, var2);
This way, passing "function" as the first parameter of "MyFun" works. But why do I have such an ambiguity and I can't call MyFun by just typing MyFun2 as the first parameter? And why auto won't figure out the "right" type?
Thank you :)
You're getting the no matching function for call to...
error std::function
doesn't have deduction guides for deducing the signature of a function pointer.
When you do this:
auto function = MyFun2;
The function, MyFun2
is decayed to a function pointer. It doesn't make sense to store the value of a function in a variable because, well, what is the value of a function? It's a block of machine instructions. Why would you ever want to copy that around? The language assumes that you won't so a function is decayed to a function pointer. The above is equivalent to this:
double (*function)(std::array<double, 3> &var) = MyFun2;
You found one solution to the error and that is to construct a std::function
from the function pointer directly. Another solution would be to avoid std::function
altogether.
template <size_t SIZE>
double MyFun(double (*f)(std::array<double, SIZE>&), std::array<double, SIZE> &x, std::array<double, SIZE> &y){
instructions;
}
So now your original example works
something = MyFun(MyFun2, var, var2);