从重载集中调用具有特定函数的函子

Call a functor with a specific function from an overload set

本文关键字:函数 重载 集中 调用      更新时间:2023-10-16

上下文

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

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

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

(G++-8.1) 错误:调用"invoke(<未解析的重载函数类型>,双精度)"没有匹配的函数

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

问题

如何从重载集中命名特定函数?我们可以用什么替换LEFTRIGHT以便以下内容格式正确并执行预期(例如,选择double std::sin(double))?

#include <functional>
#include <cmath>
int main()
{
    (void) std::invoke(LEFT std::sin RIGHT, 0.0);
}

如果这是不可能的,有没有办法定义一个函子,使其能够感知过载集?

我知道最简单的

方法是使用 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);

如何从重载集中命名特定函数?

static_cast . 例如

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

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

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

在Qt中,我们一直很难解决将重载函数的地址引入到引入助手的问题。我在这里讨论了这种帮助程序的可能实现。

此处提供了static_cast用法的规范性参考。