// defer.hpp
#pragma once
#include <functional>
namespace toolkit {
class scope_exit {
public:
scope_exit() = default;
scope_exit(const scope_exit&) = delete;
scope_exit& operator=(const scope_exit&) = delete;
scope_exit(scope_exit&&) = default;
scope_exit& operator=(scope_exit&&) = default;
template <typename F, typename... Args>
scope_exit(F&& f, Args&&... args)
{
func_ = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
}
~scope_exit()
{
if (func_) {
func_();
}
}
private:
using Callable = std::function<void()>;
Callable func_;
};
} // namespace toolkit
#define _CONCAT(__x, __y) __x##__y
#define _MAKE_SCOPE(__x) toolkit::scope_exit _CONCAT(defer, __x) = [&]()
#define SCOPE_GUARD _MAKE_SCOPE(__LINE__)
使用:
// main.cpp
#include <iostream>
#include <string>
#include "defer.hpp"
int main(int argc, char** argv)
{
void* foo = (void*)malloc(10);
SCOPE_GUARD
{
std::cout << "free" << std::endl;
free(foo);
};
void* foo1 = (void*)malloc(10);
SCOPE_GUARD
{
std::cout << "free" << std::endl;
free(foo1);
};
return 0;
}