I want to call two versions of the same function, in a function. For example:
template<class F>
auto ulp_error(F f, float x)
{
float f1 = f(x);
double x2 = x;
float f2 = static_cast<float>(f(x2));
return boost::math::float_distance(f1, f2);
}
Now I'd like to call this function via:
ulp_error(std::log, 1.2f);
but I get the following error on clang-1000.11.45.5:
fatal error: no matching function for call to 'ulp_error'
ulp_error(std::log, 1.2f);
note: candidate template ignored: couldn't infer template argument 'F'
Ok, how about this?
ulp_error<decltype(std::log)>(std::log, 1.2f);
which gives the following error:
fatal error: reference to overloaded function could not be resolved; did you mean to call it?
ulp_error<decltype(std::log)>(std::log, 1.2f);
How can I pass (say) std::log
as an argument to a function and call it with two different types?
Maybe as follows?
ulp_error([](auto x){ return std::log(x); }, 1.2f);
I mean... std::log
is a overloaded function; so using simply std::log
(or decltype(std::log)
doesn't works because the compiler can't choose the correct version. And you can't pass both of they.
But passing it inside a generic-template, the corrected version is selected by the type of the x
lambda parameter.
Another possible solution should be casting to the correct type, by example
ulp_error(static_cast<double(*)(double)>(&std::log), 1.2f);
but (MHO) I find this syntax a little ugly.