C++ 尝试catch finally构造-是否使用C++;11?
可能重复:C++ 尝试catch finally构造-是否使用C++;11?,c++,c++11,C++,C++11,可能重复: C++11是否支持try/catch/finally构造? 我这么问是因为我在任何地方都找不到关于它的信息。 谢谢。 < P> C++中,你不需要最后< /C> >因为C++有更好的。< /P> < P> C++ 11不添加对的支持。许多年来,决策者(尤其是)一直倾向于使用其他习语,即RAII。我认为C++是不太可能包含最后< /C> > < /P> < P>不是放弃RAII的借口,但在使用非RAI意识API时:是有用的。 template<typename Functor&
C++11是否支持try/catch/finally构造?
我这么问是因为我在任何地方都找不到关于它的信息。
谢谢。 < P> C++中,你不需要<代码>最后< /C> >因为C++有更好的。< /P> < P> C++ 11不添加对<代码>的支持。许多年来,决策者(尤其是)一直倾向于使用其他习语,即RAII。我认为C++是不太可能包含<代码>最后< /C> > < /P> < P>不是放弃RAII的借口,但在使用非RAI意识API时:是有用的。
template<typename Functor>
struct finally_guard {
finally_guard(Functor f)
: functor(std::move(f))
, active(true)
{}
finally_guard(finally_guard&& other)
: functor(std::move(other.functor))
, active(other.active)
{ other.active = false; }
finally_guard& operator=(finally_guard&&) = delete;
~finally_guard()
{
if(active)
functor();
}
Functor functor;
bool active;
};
template<typename F>
finally_guard<typename std::decay<F>::type>
finally(F&& f)
{
return { std::forward<F>(f) };
}
请注意,如果不需要翻译或以其他方式处理异常,则不需要使用try
块
虽然我的示例使用了C++11功能,但C++03也提供了相同的通用功能(尽管没有lambdas)。在我看来,RAII的问题在于它强烈限制了类层次结构设计。有些情况下,您需要清理,但自然没有可用的类来强制清理。@David Heffernan,幸运的是,有了lambdas,使用范围保护比以往任何时候都容易。:)正如其他人所说,C++11不直接支持finally关键字。但是,可以实现并使用seamlessy。请看我的答案:也看我的try-finally语句模仿版本:但是RAII并不总是==finally。你不能通过提供一个完整的疯狂片段来真正显示对final的需要:p。我不认为这是疯狂的。它清楚地表明,在某些情况下,根据错误需要不同的方法,最后是一种干净的方法。而且,这不能像使用计算机那样干净地完成RAII@smallB:它可以:
scoped\u ptr v=newsome\u struct;载荷矢量(v)代码>。如果load\u vector
抛出,则不会泄漏v
中的内存。完成(+代码更可读)。Downvote,一个例子是值得赞赏的。你如何保证析构函数不会被调用两次?@Samuel Good catch。这确实需要一个标志来检查*的当前状态(例如,从对象移动的对象将被停用)。我确实在我的实际代码中修复了它,我正在更新这个答案。这是否得到了预期的优化?e、 g.支票被取消了吗?@Samuel先生,没有办法提前告诉你。完全避免该标志的唯一方法是使用对临时对象的绑定:finally\u guard&&guard={std::move(functor)}代码>。这正是一种结构。它不能重构为函数(在函数中获取值意味着构造或返回一个没有生命周期扩展的悬空引用),但可以重构为宏。但是,由于decltype
,这不适用于lambda表达式。所以你不可能全部赢。
auto resource = /* acquire */;
auto guard = finally([&resource] { /* cleanup */ });
// using just
// finally([&resource] { /* cleanup */ });
// is wrong, as usual