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");
Другие вопросы по тегам