存储在std :: function中时,无捕获的lambda无法转换为函数指针

Joh*_*son 15 c++ syntax lambda function-pointers c++11

通常,没有捕获的C++ lambda 应该可以转换为c风格的函数指针.不知何故,使用它进行转换std::function::target不起作用(即返回nullptr),target_type即使它看起来是相同的,也与签名类型不匹配.

在VC13和GCC 5.3/5.2.0/4.8上测试

最小的测试示例:

#include <functional>
#include <iostream>

void Maybe() {

}

void callMe(std::function<void()> callback) {
    typedef void (*ftype)();
    std::cout << (callback.target_type() == typeid(ftype)) << std::endl;
    std::cout << callback.target<ftype>() << std::endl;
}

int main() {
    callMe([] () {});
    callMe(Maybe);
}
Run Code Online (Sandbox Code Playgroud)

预期产量将是

1
<address>
1
<address>
Run Code Online (Sandbox Code Playgroud)

实际产出

0
0
1
<address>
Run Code Online (Sandbox Code Playgroud)

问题是:为什么lambda的签名与传递的函数不同?

Que*_*tin 16

在你的第一次调用中,std::function没有把lambda腐烂成指针的麻烦,它只是存储它的实际类型(实际上并非如此void()).

您可以通过简单地使用一元来强制lambda 在使用后者构造之前衰减为指针:std::function+

callMe(+[](){});
//     ^
Run Code Online (Sandbox Code Playgroud)

  • +1,但是:我真的*不喜欢这个`+`hack for integral/pointer type coercion.它只是模糊了太多的意图.最好通过将其包装到专用函数中使其明确. (4认同)