Overloading function when passing lambda as parameter

雨燕双飞 提交于 2019-12-23 14:53:05

问题


I'm trying to implement template function when return parameter is either void or T. I tried different variations of the code above using sfinae but still not sure if that is in general possible in case lamdba is function parameter. The following code does not compile :

#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 :

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>'

wandbox live


回答1:


This is because template deduction needs a perfect-ish match for each of the function arguments in order to successfully deduce the template parameters.

You'd need to templetize the function object itself:

#include <type_traits>

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

Usage:

#include <iostream>

int main()
{
    std::cout << Apply([]() { return 42; }) << "\n";
}

live demo




回答2:


Unfortunately you can't do that because the implicit conversion (from lambda closure type to std::function) is not considered in template argument deduction; the code fails because T can't be deduced.

You can use the lambda closure type as the parameter type directly, and declare the return type as auto to be deduced automatically. e.g.

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

LIVE



来源:https://stackoverflow.com/questions/48424942/overloading-function-when-passing-lambda-as-parameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!