问题说明
原始问题,代码如下会编译报错:
using DecisionFn = bool(*)();class Decide
{
public:Decide(DecisionFn dec) : _dec{dec} {}
private:DecisionFn _dec;
};int main()
{int x = 5;Decide greaterThanThree{ [x](){ return x > 3; } };return 0;
}
原因分析
lambda表达式转成函数指针,当lambda没有捕获变量的时候,可以隐式转为指针函数
§ 5.1.2 The closure type for a lambda-expression with no
lambda-capture has a public non-virtual non-explicit const conversion
function to pointer to function having the same parameter and return
types as the closure type’s function call operator. The value returned
by this conversion function shall be the address of a function that,
when invoked, has the same effect as invoking the closure type’s
function call operator.
解决方案
当包含有捕获变量的时候,可以使用如下方式
- 把捕获的变量作为参数来传递
typedef bool(*DecisionFn)(int);Decide greaterThanThree{ []( int x ){ return x > 3; } };Decide greaterThanThree {(x > 3) ? [](){ return true; } : [](){ return false; }};
- 使用std::function来替代原始指针
using DecisionFn = std::function<bool()>;Decide greaterThanThree { [x](){ return x > 3; } };
参考:
https://stackoverflow.com/questions/7852101/c-lambda-with-captures-as-a-function-pointer
https://stackoverflow.com/questions/28746744/passing-capturing-lambda-as-function-pointer