将 lambda 作为参数传递时的重载函数

Overloading function when passing lambda as parameter

本文关键字:重载 函数 参数传递 lambda      更新时间:2023-10-16

当返回参数为 void 或 T 时,我正在尝试实现模板函数。我使用 sfinae 尝试了上述代码的不同变体,但仍然不确定在 lamdba 是函数参数的情况下这是否通常可行。以下代码不编译:

#include <functional>
template <typename T>
T Apply(const std::function<T()>& func)
{
    return func();
}
template <>
void Apply(const std::function<void()>& func)
{
    func();
}
int main(int argc, char *argv[])
{
    int i1 = Apply([]() { return 10; });
    bool b1 = Apply([]() { return true; });
    Apply([]() { return; });
    return 0;
}

错误:

error C2672: 'Apply': no matching overloaded function found
error C2784: 'T Apply(const std::function<T(void)> &)': could not deduce     template argument for 'const std::function<T(void)> &' from 'main::<lambda_536cc9cae26ef6d0d1fbeb7b66a2e26b>'

魔杖盒直播

不幸的是,

你不能这样做,因为隐式转换(从 lambda 闭包类型到 std::function (在模板参数推导中不考虑; 代码失败,因为无法推断T

您可以直接使用 lambda 闭包类型作为参数类型,并将返回类型声明为要自动推导的auto

例如
template <typename T>
auto Apply(T func)
{
    return func();
}

这是因为模板推导需要对每个函数参数进行完美匹配才能成功推导出模板参数。

你需要对函数对象本身进行寺庙化:

#include <type_traits>
template <class Function, class Return = std::result_of_t<Function()>>
Return Apply(Function func)
{
    return func();
}

用法:

#include <iostream>
int main()
{
    std::cout << Apply([]() { return 42; }) << "n";
}

现场演示