Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling two versions of the same template function passed as an argument in C++

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?

like image 564
user14717 Avatar asked Jan 30 '26 18:01

user14717


1 Answers

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.

like image 178
max66 Avatar answered Feb 02 '26 06:02

max66