The problem is that std::abs (from <complex> ) takes the std::complex<T> parameter as a reference to a constant. The function pointer speaks only by value, which causes a mismatch. The following code compiles just fine:
#include <vector> #include <complex> template <class T> void apply(const std::vector<std::complex<T> >& in, std::vector<T>& out, T (*f)(std::complex<T> const&)) { out.resize(in.size()); for(size_t i = 0; i < in.size(); ++i) out[i] = f(in[i]); } int main(){ std::vector<std::complex<float> > vcomp; std::vector<float> vf; apply(vcomp, vf, &std::abs<float>); }
Live example on Ideone.
A better idea, however, would be to simply take the type of the function as a template parameter:
template <class T, class F> void apply(const std::vector<std::complex<T> >& in, std::vector<T>& out, F f) { out.resize(in.size()); for(size_t i = 0; i < in.size(); ++i) out[i] = f(in[i]); }
Live example on Ideone.
In any case, you may sometimes need to eliminate the ambiguity on the call site with a throw if the function is templated and overloaded (I donβt remember one of the third-party <complex> functions, but you never know).
// taking std::abs as an example. It not actually templated *and* overloaded typedef float (*func_ptr)(std::complex<float> const&); apply(vcomp, vf, (func_ptr)&std::abs<float>);
source share