Статический массив лямбда-функций (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
это становится хуже, так как он говорит: "не может быть инициализирован непостоянным выражением, когда объявленный."
почему лямбда-функция непостоянна? Я что-то упускаю?
2 ответов
при создании constexpr
объект, все, что вы передаете в него, должно быть основным постоянным выражением, [decl.constexpr] / 9:
A
constexpr
спецификатор, используемый в объявлении объекта, объявляет объект какconst
. Такой объект должен иметь литеральный тип и должен быть инициализирован. Если он инициализируется вызовом конструктора,этот вызов должен быть постоянным выражением (5.19).
and, from [expr.const] лямбды не постоянны выражения1:
A условное выражение e это выражение константы ядра если оценка e, следуя правилам абстрактная машина (1.9), будет оценивать одно из следующих выражений:
- [...]
- лямбда-выражения (5.1.2);
- [...]
однако это применимо только к constexpr
, а не const
, поэтому вы могли бы просто сделать это вместо этого:
static const MyStruct ops[6] = {
{'+', [] (double a, double b) { return a+b; } },
{'-', [] (double a, double b) { return a-b; } },
};
Примечание: ваши лямбды не нужно ничего захватывать, так что вы должны просто пустой список захвата []
.
1As dyp указывает, есть предложение изменить это: N4487
захват лямбда не может распадаться на указатель функции.
и оператор для возврата указателя функции из (не захвата) лямбда не constexpr
.