Open apolukhin opened 3 years ago
Игорь, 29 ноября 2017, 14:01 То есть, если мы не выполним .release() у нас по ошибке может произойти двойное очищение ресурсов? Как то не безопасно, следить получается нужно будет за тем чтобы не забыть написать .release() и чтобы выполнение кода дошло до .release() и чтобы release() находился после ручного освобождения ресурсов.
Если такое и делать, то тогда release внутри должен не просто переключать флаг, а еще и выполнять код. Тогда, вероятно это будет работать. Но при этом нужно будет помнить, что вне функции .release освобождать ресурс нельзя. И тогда, можно спокойно забывать писать функцию release и guard вызовет code при своем уничтожении
Antervis, 1 декабря 2017, 22:41 с таким синтаксисом можно и unique_ptr для подобного использовать. Хорошая реализация бы выглядела как-то так: scoped_exit(=) { close(fd); } Стоит ли тащить в ядро языка то, что можно сделать на макросе, при тенденции уходить от макросов?
Andrey Davydov, 4 декабря 2017, 11:50 Proposal на подобную штуку (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0052r3.pdf) уверенно движется в C++20 (на сколько я могу судить со стороны, сам я никакого отношения к работе комитета не имею).
В C++20 не пролезло https://wg21.link/p0052 , решили внести в Library Funcdamentals TS 3
Перенос предложения: голоса +5, -1 Автор идеи: ??
Для обеспечения нужного уровня безопасности исключений бывает необходимо при выходе из области видимости выполнить какой-то код (например, освободить ресурс) даже, если код прерван исключением. При этом не всегда удобно создавать отдельный объект, управляющий ресурсом, например, если идет работа с чисто C-шным кодом. Для этого я предлагаю стандартизировать scope_guard и on_exception_guard, со вспомогательными методами их создания make_scope_guard() make_on_exception_guard().
При использовании такого кода в реальности оптимизитор выбросит все ненужное, в т.ч. и создание объекта scope_guard, при этом сгенерирует код, в котором при любом выходе из области видимости будет вызван close().
При вызове make_scope_guard(), создается объект scope_guard и ему передается лямбда для выполнения в деструкторе ~scope_guard(). Также у scope_guard есть метод release() для отмены выполнения кода в деструкторе и для симметричности acquire(), хотя не уверен, что он нужен. Примерная реализация:
У такого подхода есть один мелкий недочет - при создании scope_guard может вылететь исключение, однако, это возможно только при копировании захватываемых переменных по значению, однако в реальности все сколько-нибудь нетривиальные переменные scope_guard будет захватывать по ссылке.
on_exception_guard отличается от scope_guard лишь тем, что выполняет переданный код в деструкторе только при выходе из области видимости по исключению. В нужности методов release(), а тем более acquire() я сильно сомневаюсь. Реализация:
P.S. Можно обсуждать имена методов и типов, их функциональность и реализацию, но, по-моему, бесспорно, что нечто с функциональностью scope_exit давно пора стандартизировать.