This question already has answers here:
How to convert a lambda to an std::function using templates

(8个答案)


6年前关闭。




我有以下代码(简化):
#include <functional>
template <typename... Args> void Callback(std::function<void(Args...)> f){
    // store f and call later
}
int main(){
    Callback<int, float>([](int a, float b){
        // do something
    });
}

其目的是获取一些额外的参数,发送数据包,处理响应并使用结果调用lambda
问题是,它不需要lambda。
# g++ -std=c++11 test.cpp
test.cpp: In function ‘int main()’:
test.cpp:8:3: error: no matching function for call to ‘Callback(main()::<lambda(int, float)>)’
test.cpp:8:3: note: candidate is:
test.cpp:2:34: note: template<class ... Args> void Callback(std::function<void(Args ...)>)
test.cpp:2:34: note:   template argument deduction/substitution failed:
test.cpp:8:3: note:   ‘main()::<lambda(int, float)>’ is not derived from ‘std::function<void(Args ...)>’

有什么方法可以使此工作正常进行,而无需经历将lambda明确包装在std::function中的麻烦?
Callback(std::function<void(int, float)>([](int a, float b){
    // do something
}));

即使省略了Callback模板参数(如此处所示),也可以正常工作。
虽然仍然有“额外的” std::function。

为什么不能自己找出转换?它适用于非模板:
void B(std::function<void(int, float)> f){/* ... */};
int main(){
    B([](int a, float b){
        // do something
    });
}

供引用,我正在使用

最佳答案

您可以使用专用 Actor 表。一旦有了这样的工具

#include <functional>

using namespace std;

template<typename T>
struct memfun_type
{
    using type = void;
};

template<typename Ret, typename Class, typename... Args>
struct memfun_type<Ret(Class::*)(Args...) const>
{
    using type = std::function<Ret(Args...)>;
};

template<typename F>
typename memfun_type<decltype(&F::operator())>::type
FFL(F const &func)
{ // Function from lambda !
    return func;
}

您可以对所有lambda类型说FFL(),以将其转换为std::function的正确版本
int main()
{
    Callback(FFL([](int a, float b){
        // do something
    }));

    return 0;
}

Display

09-10 05:23
查看更多