我正在尝试编写一个基于Alexandrescu概念但使用c ++ 11习语的简单ScopeGuard.
namespace RAII
{
template< typename Lambda >
class ScopeGuard
{
mutable bool committed;
Lambda rollbackLambda;
public:
ScopeGuard( const Lambda& _l) : committed(false) , rollbackLambda(_l) {}
template< typename AdquireLambda >
ScopeGuard( const AdquireLambda& _al , const Lambda& _l) : committed(false) , rollbackLambda(_l)
{
_al();
}
~ScopeGuard()
{
if (!committed)
rollbackLambda();
}
inline void commit() const { committed = true; }
};
template< typename aLambda , typename rLambda>
const ScopeGuard< rLambda >& makeScopeGuard( const aLambda& …Run Code Online (Sandbox Code Playgroud) 我为C++ 11编写了一个小实用程序类,我将其用作范围保护,以便更轻松地处理异常安全和类似的事情.
看起来有点像黑客.但我很惊讶我没有在使用C++ 11功能的其他地方看到它.我认为boost与C++ 98类似.
但这是个好主意吗?或者是否有我错过的潜在问题?在boost或类似的解决方案中是否已经有类似的解决方案(使用C++ 11功能)?
namespace detail
{
template<typename T>
class scope_exit : boost::noncopyable
{
public:
explicit scope_exit(T&& exitScope) : exitScope_(std::forward<T>(exitScope)){}
~scope_exit(){try{exitScope_();}catch(...){}}
private:
T exitScope_;
};
template <typename T>
scope_exit<T> create_scope_exit(T&& exitScope)
{
return scope_exit<T>(std::forward<T>(exitScope));
}
}
#define _UTILITY_EXIT_SCOPE_LINENAME_CAT(name, line) name##line
#define _UTILITY_EXIT_SCOPE_LINENAME(name, line) _UTILITY_EXIT_SCOPE_LINENAME_CAT(name, line)
#define UTILITY_SCOPE_EXIT(f) const auto& _UTILITY_EXIT_SCOPE_LINENAME(EXIT, __LINE__) = ::detail::create_scope_exit(f)
Run Code Online (Sandbox Code Playgroud)
并且使用了类似的东西.
int main ()
{
ofstream myfile;
myfile.open ("example.txt");
UTILITY_SCOPE_EXIT([&]{myfile.close();}); // Make sure to close file even in case of exception
myfile << "Writing …Run Code Online (Sandbox Code Playgroud)