我想做这样的事情(在课堂上):
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函数不是常数?我错过了什么吗?
当你构造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不需要捕获任何东西,所以你应该只是空的捕获列表[].