I'd like to do something like this (inside a class):
static constexpr MyStruct ops[6] = {
    {'+', [&] (double a, double b) { return a+b; } },
    {'-', [&] (double a, double b) { return a-b; } },
    ...
};
Where MyStruct is defined as:
typedef double (*binOp)(double, double);
struct MyStruct {
    char c;
    binOp fn;
};
I also tried:
std::function <double(double,double)> fn;
for the definition of fn, but no luck.
The error I get for the first case is "error: field initializer is not constant" which I don't really get. If I try with std::function it gets worse, since it says: "cannot be initialized by a non-constant expression when being declared".
Why is the lambda function non-constant? Am I missing something?
capturing lambda cannot decay to function pointer.
and operator to return the function pointer from a (non-capturing) lambda is not constexpr.
When you construct constexpr object, everything you pass into it needs to be a core constant expression, [decl.constexpr]/9:
A
constexprspecifier used in an object declaration declares the object asconst. 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).
and, from [expr.const] lambdas are not constant expressions1:
A conditional-expression e 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);
 - [...]
 
However, that applies only to constexpr and not to const, so you could simply do that instead:
static const MyStruct ops[6] = {
    {'+', [] (double a, double b) { return a+b; } },
    {'-', [] (double a, double b) { return a-b; } },
};
Note: your lambdas don't need to capture anything, so you should just empty the capture list [].
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With