0

让我们问一下这个简单的范围保护:

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 析构函数之前调用?

4

2 回答 2

2

是的,它是安全的。宏将 lambda 存储在局部变量中。局部变量的破坏顺序是固定的(与构造相反)。因此可以保证~finop_t()在相应的 lambda ( FIN ## l ## clo) 析构函数之前调用析构函数。

于 2015-08-10T17:40:28.617 回答
2

局部变量的破坏与它们的构造相反。

这是一种更有效的方法,它不需要引用并使用复制省略来就地构造 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;
}
于 2015-08-10T17:54:50.510 回答