C++11 лямбда-захваченных с помощью ссылки тривиально разрушаемы
Я хотел бы знать, если следующие утечки памяти или нет (указано в стандарте)
...
jmp_buf env;
if(setjmp(env) == 0) {
auto lambda = [&] () {
...
longjmp(env, 1);
};
lambda();
}
что сводится к тому, имеют ли лямбды, захватывающие ссылки, тривиальный деструктор (я полагаю)?
Я знаю, что это, вероятно, злой, но, тем не менее, должно быть сделано.
1 ответ
Это зависит от реализации. Вы можете разумно ожидать, что это будет правдой, но вот что говорит стандарт (N4140, [expr.prim.lambda]/3, выделение мое):
Реализация может определять тип замыкания иначе, чем описано ниже, при условии, что это не изменяет наблюдаемое поведение программы, кроме как путем изменения:
- размер и / или выравнивание типа укупорки,
- является ли тип закрытия тривиально копируемым (раздел 9),
- является ли тип замыкания классом стандартной компоновки (раздел 9), или
- является ли тип замыкания классом POD (раздел 9).
И по определению в [класс] / 3
Тривиально копируемый класс - это класс, который:
- не имеет нетривиальных конструкторов копирования (12.8),
- не имеет нетривиальных конструкторов перемещения (12.8),
- не имеет нетривиальных операторов присвоения копии (13.5.3, 12.8),
- не имеет нетривиальных операторов назначения перемещения (13.5.3, 12.8), и
- имеет тривиальный деструктор (12.4).
Таким образом, реализация позволяет создавать нетривиальный деструктор для лямбды.
Тем не менее, вы можете проверить, сделала ли ваша конкретная реализация лямбда-тривиально разрушаемой, следующим образом:
auto lambda = [&]{ /*...*/ };
static_assert(std::is_trivially_destructible<decltype(lambda)>::value, "Lambda isn't trivially destructible");