lambda函数的静态数组(C++)

Dav*_*.F. 10 c++ lambda c++11

我想做这样的事情(在课堂上):

static constexpr MyStruct ops[6] = {
    {'+', [&] (double a, double b) { return a+b; } },
    {'-', [&] (double a, double b) { return a-b; } },
    ...
};
Run Code Online (Sandbox Code Playgroud)

在哪里MyStruct定义为:

typedef double (*binOp)(double, double);
struct MyStruct {
    char c;
    binOp fn;
};
Run Code Online (Sandbox Code Playgroud)

我也尝试过:

std::function <double(double,double)> fn;
Run Code Online (Sandbox Code Playgroud)

对于定义fn,但没有运气.

我得到的第一种情况的错误"错误:字段初始化程序不是常量",我真的没有.如果我尝试std::function它会变得更糟,因为它说:"在声明时不能通过非常量表达式初始化".

为什么lambda函数不是常数?我错过了什么吗?

Bar*_*rry 8

当你构造constexpr对象时,你传递给它的一切都需要是一个核心常量表达式,[decl.constexpr]/9:

constexpr对象声明中使用的说明符将对象声明为const.这样的对象应具有文字类型并应初始化.如果它是由构造函数调用初始化的,那么该调用应该是一个常量表达式(5.19).

并且,从[expr.const] lambdas不是常量表达式1:

条件表达式 Ë是一个核心常量表达式除非的评价Ë,以下抽象机(1.9),将评估下面的表达式中的一个的规则:

  • [...]
  • 一个lambda表达式(5.1.2);
  • [...]

但是,这仅适用于constexpr而不适用const,因此您可以简单地执行此操作:

static const MyStruct ops[6] = {
    {'+', [] (double a, double b) { return a+b; } },
    {'-', [] (double a, double b) { return a-b; } },
};
Run Code Online (Sandbox Code Playgroud)

注意:你的lambda不需要捕获任何东西,所以你应该只是空的捕获列表[].


1正如dyp所指出的那样,有一项建议要改变这一点:N4487