c++:另一个简单的作用域保护

C++ : other one simple scope guard

本文关键字:作用域 保护 简单 另一个 c++      更新时间:2023-10-16

让我们问一下这个简单的作用域保护:

template <class T>
struct finop_t {
    T& t;
    ~finop_t() { t(); }
};
#define FINALLY__(l, cl) 
    auto FIN ## l ## clo = cl; 
    finop_t<decltype(FIN ## l ## clo)> FIN ## l ## fin { FIN ## l ## clo}
#define FINALLY_(l, cl) FINALLY__(l, cl)
#define FINALLY(...) FINALLY_(__LINE__, ([=](){__VA_ARGS__}))
int main() {
    FINALLY( std::cout << "hello" << std::endl ; );
    std::cout << "one" << std::endl;
    FINALLY( std::cout << "world" << std::endl ; );
    std::cout << "second" << std::endl;
    return 0;
}

在这里依赖销毁顺序安全吗?即,它是安全的假设~finop_t()将在lambda析构函数之前调用?

是的,它是安全的。宏将lambda存储在一个局部变量中。局部变量的销毁顺序是固定的(与构造顺序相反)。这样就保证了~finop_t()析构函数在相应的lambda (FIN ## l ## clo)析构函数之前被调用。

局部变量的销毁顺序与它们的构造顺序相反。

这里有一个更有效的方法,它不需要引用,并使用复制-省略来原地构造lambda。

(注意,您可能想要考虑[&]而不是[=],但这取决于您的判断)

#include <iostream>
template <class T>
struct finop_t {
    finop_t(T&& t) : t(std::forward<T>(t)) {}
    T t;
    ~finop_t() { t(); }
};
template<class F>
finop_t<F> make_finop_t(F&& f)
{
    return finop_t<F>(std::forward<F>(f));
}
#define FINALLY__(l, cl) 
auto FIN ## l ## fin = make_finop_t(cl);
#define FINALLY_(l, cl) FINALLY__(l, cl)
#define FINALLY(...) FINALLY_(__LINE__, ([=](){__VA_ARGS__}))
int main() {
    FINALLY( std::cout << "hello" << std::endl ; );
    std::cout << "one" << std::endl;
    FINALLY( std::cout << "world" << std::endl ; );
    std::cout << "second" << std::endl;
    return 0;
}