Я читал про инструкцию defer. Он позволяет указать действие, которое нужно предпринять, когда функция закончилась. Например, если у вас есть указатель на файл или ресурс, вместо того, чтобы писать бесплатный/удалить с любым возможным обратным путем, вам просто нужно указать функцию отсрочки один раз.golang-style "defer" in C++
Похоже, что аналог может появиться на C++ в конце концов (What is standard defer/finalizer implementation in C++?, Will there be standardization of scope guard/scope exit idioms?). До тех пор, есть ли что-нибудь непредвиденное в том, чтобы делать это с объектом, деструктор которого выполняет обратный вызов? Он выглядит как destructor order for local variables is sane и что он также отлично справляется с исключениями, хотя, возможно, не выходит из сигналов.
Вот пример реализации ... есть ли что-то тревожное?
#include <iostream>
#include <functional>
using namespace std;
class FrameExitTask {
std::function<void()> func_;
public:
FrameExitTask(std::function<void()> func) :
func_(func) {
}
~FrameExitTask() {
func_();
}
FrameExitTask& operator=(const FrameExitTask&) = delete;
FrameExitTask(const FrameExitTask&) = delete;
};
int main() {
FrameExitTask outer_task([](){cout << "world!";});
FrameExitTask inner_task([](){cout << "Hello, ";});
if (1+1 == 2)
return -1;
FrameExitTask skipped_task([](){cout << "Blam";});
}
Выход: Hello, world!
Это может быть более подходящим для [Просмотр Кода] (http://codereview.stackexchange.com). Обратите внимание, что уже существует множество реализаций этого класса ScopeGuard, поэтому зачем изобретать колесо? Некоторые реализации, которые я знаю, имеют различные преимущества или специальные инструменты, которые я бы предпочел для вашей версии (например, никакого стирания типа). – dyp
Проблема в том, что каждый класс должен уже делать то, что вы делаете в своем деструкторе, поэтому варианты использования на C++ намного реже, чем в Go. Если вы ищете существующие реализации, проверьте boost.ScopeExit. Думаю, что у Фолли Фолса тоже есть. – inf
Возможно, вам лучше пометить деструктор 'noexcept'. Если функция, которую вы используете 'FrameExitTask', возвращается нормально, исключение из вашего обработчика finally, вероятно, будет работать. Если функция выходит из-за какого-либо другого исключения, то второе исключение из вашего обработчика вызовет проблемы. –