我们的需求

可能有这样的需求,

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 ++:依靠RVO最终功能 | 码农家园​

​​C++匿名函数_co16zero的博客-c++匿名函数​​