2015-05-29 70 views
11

我想这样做(一类中)静态数组:lambda函数(C++)

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

MyStruct定义为:

typedef double (*binOp)(double, double); 
struct MyStruct { 
    char c; 
    binOp fn; 
}; 

我也尝试:

std::function <double(double,double)> fn; 

定义fn,但没有运气。

我得到的第一个案例的错误是“错误:字段初始值设定项不是常量”我真的不明白。如果我尝试使用std::function,它会变得更糟,因为它说:“声明时不能用非常量表达式初始化”。

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

+1

替换'和'const' constexpr'。 – Nawaz

+4

lambda表达式当前可能不会出现在常量表达式中,但是最终可能会删除该限制:https://isocpp.org/files/papers/N4487.pdf – dyp

回答

9

当构造constexpr对象,就通入它的一切必须是一个核心常量表达式,[decl.constexpr]/9:

A constexpr specifier used in an object declaration declares the object as const . Such an object shall have literal type and shall be initialized. If it is initialized by a constructor call, that call shall be a constant expression (5.19).

和,从[expr.const] lambda表达式不是恒定表达式:

A conditional-expressione is a core constant expression unless the evaluation of e, following the rules of the abstract machine (1.9), would evaluate one of the following expressions:

  • [...]
  • a lambda-expression (5.1.2);
  • [...]

然而,这仅适用于constexpr,而不是const,所以你可以简单地这样做,而不是:

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

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


作为dyp指出的,就是要改变这样的建议:N4487

0

捕获lambda不能衰减到函数指针。

和运算符从(非捕获)lambda返回函数指针不是constexpr