defer 的实现

  • ​​defer的实现​​

在go语言中有一个关键字 defer 可以用来指示当程序跳出某一作用域的时候执行指定的操作。假定C++中也定义了defer操作,则以下代码将产生对应的操作:

#include <iostream>
#include <function>

void func()
{
std::cout << "defer:func()" << std::endl;
}

class scope
{
public:
void print(){
std::cout << "defer:scope()" << std::endl;
}
};

int main()
{
defer func;
defer [](){
std::cout << "defer:lambda()" << std::endl;
};

{
scope tmp;
defer [=](){
tmp.print();
};
}

// defer:scope()
// defer:lambda()
// defer:func()
return 0;
}

defer的实现

defer的实现借助于C++的以下特性:

  • std::function
  • 模板的完美转发
  • RAII:对象销毁的时候调用该对象的析构函数
  • 类的operator重载操作

另外,为了方便创建对象,还使用了宏来创建对象。

#include <functional>
#include <iostream>
#include <string>

// https://blog.csdn.net/cai6811376/article/details/103497566

#define _DEFER_CONNECT(x, y) x##y
#define _DEFER_CREATE_(x, y) _DEFER_CONNECT(x, y)

// auto __defer__line__ = create_defer() + xxx;
// create_defer(): 创建一个匿名对象,然后调用operator+生成一个 __defer_action 对象
#define defer auto _DEFER_CREATE_(__defer__, __LINE__) = create_defer() +
#define defer_scope defer[&]

struct __defer_action
{
std::function<void()> _function;

template <class T>
__defer_action(T &&f) : _function(std::forward(f)) {}

__defer_action(__defer_action &&f) : _function(std::move(f._function)) {}

__defer_action &operator=(__defer_action &&rhs) noexcept
{
_function = std::move(rhs._function);
return *this;
}

~__defer_action()
{
if (_function)
{
_function();
}
}
};

struct create_defer
{
template <class T>
__defer_action operator+(T &&f)
{
return __defer_action{std::forward(f)};
}
};

int main()
{
int i = 0;
defer[&]()
{
std::cout << "i = " << ++i << std::endl;
};

defer_scope
{
i++;
};

return 0;
}