从过载集中调用具有特定函数的仿函数

YSC*_*YSC 4 c++ overloading overload-resolution c++17

上下文

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

这是不正确的(现场演示):

std::invoke(std::sin, 0.0);
Run Code Online (Sandbox Code Playgroud)

(g ++ - 8.1)错误:没有用于调用'invoke(<unresolved overloaded function type>,double)'的匹配函数

实际上,std::sin是一个重载集,编译器缺少类型信息来选择其中一个函数.

如何从重载集中命名特定函数?我们可以取代什么LEFT,RIGHT以便以下是良好的形式,并做出预期(例如,选择double std::sin(double))?

#include <functional>
#include <cmath>

int main()
{
    (void) std::invoke(LEFT std::sin RIGHT, 0.0);
}
Run Code Online (Sandbox Code Playgroud)

如果这是不可能的,有没有办法定义一个仿函数,所以它是重载集感知?

Nat*_*ica 6

我知道这样做的最简单方法是使用lambda来启用重载查找

std::invoke([](auto val){return std::sin(val);}, 0.0);
Run Code Online (Sandbox Code Playgroud)

将允许您传递任何值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);
Run Code Online (Sandbox Code Playgroud)

  • 虽然如果你打算使用一个宏,不妨全力以赴,`auto && ...`和` - > decltype()`和`noexcept`. (2认同)