滥用 c++11 unique_ptr 在离开作用域时执行代码
Abusing c++11 unique_ptr to execute code upon leaving the scope
我想使用 std::unique_ptr
的删除器来保证某些代码会在离开范围时执行。例如,假设我有一个 class 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
。
编辑:我想避免实用程序 classes。太简单了:)
原来的C++03ScopeGuard by Petru Marginean (and a little Andrei Alexandrescu)使用了各种技巧。使用 C++11,您可以只使用 std::function
和 lambda 表达式来完成您想要完成的事情。例如
class Scope_guard
{
private:
function<void()> cleanup_;
public:
void release() { cleanup_ = []{}; }
~Scope_guard() { cleanup_(); }
Scope_guard( function<void()> f )
: cleanup_( move( f ) )
{}
};
免责声明:编译器未触及代码。
注意:显然,纯粹主义者更喜欢将其表达为具有工厂功能的 class 模板,而像我这样的简单主义者(simpletons?)更喜欢上面的东西。但是你明白了。
你为什么不这样做"by hand"?
{
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
}
在一些头文件中定义一个 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([&](void*){/* cleanup here */});
我想使用 std::unique_ptr
的删除器来保证某些代码会在离开范围时执行。例如,假设我有一个 class 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
。
编辑:我想避免实用程序 classes。太简单了:)
原来的C++03ScopeGuard by Petru Marginean (and a little Andrei Alexandrescu)使用了各种技巧。使用 C++11,您可以只使用 std::function
和 lambda 表达式来完成您想要完成的事情。例如
class Scope_guard
{
private:
function<void()> cleanup_;
public:
void release() { cleanup_ = []{}; }
~Scope_guard() { cleanup_(); }
Scope_guard( function<void()> f )
: cleanup_( move( f ) )
{}
};
免责声明:编译器未触及代码。
注意:显然,纯粹主义者更喜欢将其表达为具有工厂功能的 class 模板,而像我这样的简单主义者(simpletons?)更喜欢上面的东西。但是你明白了。
你为什么不这样做"by hand"?
{
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
}
在一些头文件中定义一个 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([&](void*){/* cleanup here */});