c++ - 将捕获的 lambda 作为函数指针传递

标签 c++ c++11 lambda function-pointers

是否可以将 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;
}

当我 try to compile this ,我得到以下编译错误:

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 不能被视为 constexpr 因此我不能将它作为函数传递指针?我也试过制作 x constexpr,但这似乎没有帮助。

最佳答案

如果 lambda 不捕获,则只能将其转换为函数指针,来自 draft C++11 standard 5.1.2 [expr.prim.lambda] 部分说(强调我的):

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.

请注意,cppreference 在其关于 Lambda functions 的部分中也涵盖了这一点.

因此,以下替代方案可行:

typedef bool(*DecisionFn)(int);

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

这也是:

typedef bool(*DecisionFn)();

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

作为5gon12eder指出,您也可以使用 std::function , 但请注意 std::function is heavy weight ,因此这不是无成本的权衡。

关于c++ - 将捕获的 lambda 作为函数指针传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30856072/

相关文章:

c++ - 比较binary_search的功能

c++ - 如何防止 COM Server EXE 打开命令提示符窗口

c++ - 为什么这个递归函数只有在使用 ELSE 时才有效

c++ - 通过 constexpr 变量的初始化,跳转到标签编译错误是否合理

c# - 在 C# 中使用 lambda 进行流畅的接口(interface)配置

Java 8 - 匿名类和 lambda 函数之间明显的不一致

python - 使用字典交叉数据框列 "contains List"

c++ - 为什么initializer_list没有违反 "One Class-Type Conversion"的规则

c++ - 在类模板中重载赋值运算符

c++ - 为什么 is_lock_free 是一个成员函数?