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
constexpr
specifier 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