Обычная техника в c ++ - RAII . Вы создаете объект, который при разрушении будет выполнять какое-то действие. Обычно он будет что-то делать, когда создан, а также разрушен, но не обязательно.
Чтобы назвать типичный пример из стандартной библиотеки, std::ofstream
закроет файл, с которым он связан, когда он будет уничтожен. Вы можете вручную вызвать close
, но обычно это не требуется, поскольку он будет вызываться автоматически при уничтожении потока файлов.
Вы можете использовать ту же технику для вашего finally
.
#include <iostream>
template <typename F>
class RAII {
public:
RAII(F f) : func(std::move(f)) {}
~RAII() { func(); }
private:
F func;
};
template <typename F>
auto finally(F f)
{
return RAII<F>(std::move(f));
};
void test()
{
auto raii_finally = finally([]{ std::cout << "Bye" << std::endl; });
//RAII raii_finally([]{ std::cout << "Bye" << std::endl; }); <-- c++17
std::cout << "Hi " << std::endl;
}
int main(int argc, char const *argv[])
{
test();
std::cout << "End of Main" << std::endl;
return 0;
}
raii_finally
разрушается в конце функции, и в деструкторе называется лямбда, которую мы передали.
В этом случае функция избыточна, и вы можете вызвать конструктор RAII
напрямую, если используете c++17
.