使用重载集中的特定函数调用仿函数

Call a functor with a specific function from an overload set

上下文

在与数学相关的上下文中,我想定义作用于 <cmath> 函数的仿函数。出于这个问题的目的,我们将使用 std::invoke 作为我们的函子。

这是错误的 (live demo):

std::invoke(std::sin, 0.0);

(g++-8.1) error: no matching function for call to 'invoke(<unresolved overloaded function type>, double)'

确实,std::sin 是一个重载集,编译器缺少选择其中一个函数的类型信息。

问题

如何命名重载集中的特定函数?我们可以用什么来替换 LEFTRIGHT 以便下面的格式正确并且符合预期(例如,select double std::sin(double))?

#include <functional>
#include <cmath>

int main()
{
    (void) std::invoke(LEFT std::sin RIGHT, 0.0);
}

如果这不可能,有没有办法定义一个仿函数,使其具有重载集感知能力?

How could I name a specific function from an overload set?

static_cast。例如

std::invoke(static_cast< double(*)(double) >( &std::sin ), 0.0);

有更简单的方法可以解决这个问题,例如使用通用的 lambda 来避免可怕的语法:

std::invoke([](auto x){ return std::sin(x); }, 0.0);

在 Qt 中,将重载函数的地址取到 helpers have been introduced. I discussed a possible implementation of such a helper here.

的问题让我们感到有点困难

static_cast 用法的规范参考是 here

据我所知,最简单的方法是使用 lambda 启用重载查找

std::invoke([](auto val){return std::sin(val);}, 0.0);

将允许您将任何值传递给 invoke,然后 lambda 主体将处理实际调用,然后进行重载解析。

您可以使用宏将 lambda 主体从对 invoke 的调用中抽象出来,使用类似

的方法
#define FUNCTORIZE(func) [](auto&&... val) noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) {return func(std::forward<decltype(val)>(val)...);}
//...
std::invoke(FUNCTORIZE(std::sin), 0.0);