在 C++ 中调用作为参数传递的同一模板函数的两个版本

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

我想在一个函数中调用同一个函数的两个版本。例如:

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);
}

现在我想通过以下方式调用此函数:

ulp_error(std::log, 1.2f);

但我在 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'

好的,这个怎么样?

ulp_error<decltype(std::log)>(std::log, 1.2f);

出现以下错误:

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);

如何将 std::log 作为参数传递给函数并使用两种不同的类型调用它?

也许如下?

ulp_error([](auto x){ return std::log(x); }, 1.2f);

我的意思是... std::log是一个重载函数;所以简单地使用 std::log (或 decltype(std::log) 不起作用,因为编译器无法选择正确的版本。而且你不能同时传递它们。

但是将它传递到通用模板中,更正后的版本由 x lambda 参数的类型选择。

另一种可能的解决方案应该是转换为正确的类型,例如

ulp_error(static_cast<double(*)(double)>(&std::log), 1.2f);

但是 (MHO) 我觉得这个语法有点难看。