我们的需求
可能有这样的需求,
fun()
{
xx;
xx;
xx;
//希望在这里能自动执行一段设定好的代码,实现一些自动清除啥啥啥的操作
}
核心思想
在fun函数开始处,定义一个栈对象,构造函数给它传递要给匿名函数进去初始化该对象,然后fun函数结束,会自动析构这个栈对象。(然而该对象的析构函数,恰好是调用传递进去的这个匿名函数(也叫lambda函数),这样就实现了fun函数结束时候自动执行一段代码啦(这里就是那个匿名函数))。
那我们开干吧。
写法
fun()
{
auto action = finally([this]{mXX = false;});
xx;
xx;
xx;
//这里能自动执行 mXX = false;这个代码
}
实现过程
该栈对象的类,如何定义,如下:
//https://github.com/Microsoft/GSL
//这是一个模板类,相当于传进来的可以是一个函数(相当于注册回调函数),也可以是其它内容
template <class F>
class final_action
{
public:
static_assert(!std::is_reference<F>::value && !std::is_const<F>::value &&
!std::is_volatile<F>::value,
"Final_action should store its callable by value");
//构造函数,传进来的东西,比如函数,就会赋值给自己的成员 F f_;
explicit final_action(F f) noexcept : f_(std::move(f)) {}
final_action(final_action&& other) noexcept
: f_(std::move(other.f_)), invoke_(other.invoke_)
{}
final_action(const final_action&) = delete;
final_action& operator=(const final_action&) = delete;
final_action& operator=(final_action&&) = delete;
//析构函数时候,就调用f_()函数,也就是构造函数时候传进来的那个函数了喔
~final_action() noexcept
{
if (invoke_) f_();
}
private:
F f_;
bool invoke_{true};
};
template <class F> final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>
finally(F&& f) noexcept
{
return final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>(
std::forward<F>(f));
}
我们的fun函数写法如下:
void Main::fun()
{
mA = 1;
//匿名函数内容: [this]{mA = 9;}
//action就是finally构造出的对象(我们不需要使用到这个对象,因为以及可以让它自动析构即可)
auto action = finally([this]{
mA = 9;
});
mA = 2;
mA = 3;
mA = 4;
//这里action对象会被析构了,会自动执行 mA = 9;
}
参考文章:
C++匿名函数_co16zero的博客-c++匿名函数