小编典典

将捕获 lambda 作为函数指针传递

all

是否可以将 lambda 函数作为函数指针传递?如果是这样,我一定是做错了什么,因为我得到了一个编译错误。

考虑以下示例

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;
}

当我尝试编译这个时,我得到以下编译错误:

In function 'int main()':
17:31: error: the value of 'x' is not usable in a constant expression
16:9:  note: 'int x' is not const
17:53: error: no matching function for call to 'Decide::Decide(<brace-enclosed initializer list>)'
17:53: note: candidates are:
9:5:   note: Decide::Decide(DecisionFn)
9:5:   note: no known conversion for argument 1 from 'main()::<lambda()>' to 'DecisionFn {aka bool (*)()}'
6:7:   note: constexpr Decide::Decide(const Decide&)
6:7:   note: no known conversion for argument 1 from 'main()::<lambda()>' to 'const Decide&'
6:7:   note: constexpr Decide::Decide(Decide&&)
6:7:   note: no known conversion for argument 1 from 'main()::<lambda()>' to 'Decide&&'

这是一个要消化的错误消息,但我认为我从中得到的是 lambda 不能被视为
aconstexpr所以我不能将它作为函数指针传递?我也尝试过制作xconstexpr ,但这似乎没有帮助。


阅读 86

收藏
2022-04-25

共1个答案

小编典典

如果 lambda 没有捕获,则只能将其转换为函数指针,从草案 C++11 标准部分5.1.2
[expr.prim.lambda] 说( 强调我的 ):

没有 lambda 捕获 的 lambda 表达式的闭包类型具有一个公共的非虚拟非显式 const 转换函数,指向
具有与闭包类型的函数调用运算符相同的参数和返回类型的函数的指针。此转换函数返回的值应为函数的地址,该函数在调用时与调用闭包类型的函数调用运算符具有相同的效果。

请注意,cppreference 在其关于Lambda
函数
的部分中也对此进行了介绍。

因此,以下替代方案将起作用:

typedef bool(*DecisionFn)(int);

Decide greaterThanThree{ []( int x ){ return x > 3; } };

这也是这样:

typedef bool(*DecisionFn)();

Decide greaterThanThree{ [](){ return true ; } };

并且正如指出的那样,您也可以使用std::function,但请注意这std::function是重量级的,因此这不是一个成本较低的权衡。

2022-04-25