Reputation: 603
I have got template function with function pointer as a template parameter. When I use global function pointer as template parameters everything works fine. When I try to define function locally using lambda(without capturing) problems arise. Here is minimal code:
#include <vector>
#include <iostream>
template<double (*f)(double, double)>
std::vector<double> calculate(std::vector<double>& x, std::vector<double>& y){
std::vector<double> z(x.size());
std::transform(x.begin(),x.end(),y.begin(),z.begin(),f);
return z;
}
double calc(double n, double k){
return n*n+k*k;
}
int main(int argc, char *argv[])
{
double (*fun)(double,double) = [](double n, double k){return n*n+k*k;};
std::vector<double> x(5,3);
std::vector<double> y(5,4);
std::vector<double> z1 = calculate<&calc>(x,y);//it works fine
std::vector<double> z2 = calculate<fun>(x,y);//this line gives a bunch of errors
for(int i=0;i<z1.size();i++){
std::cout<<z1[i]<<" ";
}
for(int i=0;i<z2.size();i++){
std::cout<<z2[i]<<" ";
}
return 0;
}
Here is errors:
the value of 'fun' is not usable in a constant expression
no matching function for call to 'calculate(std::vector<double>&, std::vector<double>&)
'fun' is not a valid template argument for type 'double (*)(double, double)'
it must be the address of a function with external linkage
Upvotes: 1
Views: 564
Reputation: 114579
calc
is a constant and can be used as a template parameter, while instead fun
is a variable and therefore cannot.
Unfortunately you cannot pass a lambda directly as a template parameter just because you cannot (the standard says you cannot)... so the following is not going to work:
calculate<[](double n, double k){ return n*n+k*k; }>(x, y);
In you specific case however it's not clear why the function is a template parameter and not just a parameter... (in that case passing fun
would work fine).
Upvotes: 2
Reputation: 42929
You can only pass pointer to functions as template arguments if they're constexpr
.
In this case however:
double (*fun)(double,double) = [](double n, double k){return n*n+k*k;};
fun
is not, thus you cannot pass it as a template argument.
In simple words fun
is runtime variable and you cannot pass a runtime variable as template argument.
Upvotes: 0