在离开作用域时滥用c ++ 11 unique_ptr来执行代码

时间:2015-02-25 21:04:42

标签: c++ c++11 unique-ptr

我想使用std::unique_ptr的删除器来保证一些代码在离开范围时执行。例如,假设我有一个功能为Event的课程set_event()

我想确保在离开范围时,将调用函数my_event.set_event()。我设法得到类似的东西:

Event my_event;
auto releasing_function = [&my_event] (void*){my_event.set_event();};
std::unique_ptr<void, decltype(releasing_function)> safe_event((void*)1, releasing_function);

但我觉得我们可以做得更好。也许是一个没有这个自动lambda函数的衬里,或者避免这个丑陋的(void*)1。甚至可能完全删除unique_ptr

编辑:我想避免使用实用程序类。那太容易了:)

3 个答案:

答案 0 :(得分:2)

在某些标题中定义一个maker-function以便于使用:

template<class F> auto scope_guard(F&& f) {
    return std::unique_ptr<void, std::decay<F>::type>{(void*)1, std::forward<F>(f)};
}

并使用它:

auto unique = scope_guard([&]{/* cleanup here */});

答案 1 :(得分:0)

原始C ++ 03 ScopeGuard by Petru Marginean (and a little Andrei Alexandrescu)使用了各种技巧。使用C ++ 11,您可以使用std::function和lambda表达式来完成您想要的操作。 E.g。

class Scope_guard
{
private:
    function<void()> cleanup_;
public:
    void release() { cleanup_ = []{}; }
    ~Scope_guard() { cleanup_(); }
    Scope_guard( function<void()> f )
        : cleanup_( move( f ) )
    {}
};

免责声明:编译器未触及的代码。

注意:显然纯粹主义者更喜欢将其表达为具有工厂功能的类模板,而像我这样的简单(简单?)更喜欢上述内容。但是你明白了。

答案 2 :(得分:0)

为什么不这样做&#34;手工&#34;?

{
    struct Guard {
        Event my_event;
        explicit Guard (Event my_event) : my_event (my_event) { }
        ~Guard () { my_event.set_event (); }
    };
    Guard guard {my_event};

    /* ... */

   // when scope is left, guard's destructor will be called
}