直接看代码吧:
#ifndef ___UTIL_RAII_H__
#define ___UTIL_RAII_H__#include <cstddef>
#include <functional>
#include <new>
namespace M{
class IRAII
{
public:
void Abolish()throw(){
m_bAbolish = true;
}
protected:
IRAII():m_bAbolish(false){}
IRAII(IRAII&& other):m_bAbolish(other.m_bAbolish){
other.m_bAbolish = true;
}
protected:
bool m_bAbolish;
};
template <class T>
class RAII : public IRAII
{
public:
explicit RAII(const T& t)
:m_t(t){}
explicit RAII(T&& t)
:m_t(std::move(t)){}
RAII(RAII&& other)
:IRAII(std::move(other)),
m_t(std::move(other.m_t)){}
~RAII() throw(){
if(!m_bAbolish){
Invoke();
}
}
private:
void* operator new(size_t size){
return ::operator new(size);
}
void operator delete(void *ptr) throw(){
::operator delete(ptr);
}
void Invoke() throw(){ m_t();}
T m_t;
};
template <class T>
RAII<typename std::decay<T>::type> MakeRAII(T&& t){
return RAII<typename std::decay<T>::type>(std::forward<T>(t));
}
enum Finaly{};
template <class T>
RAII<typename std::decay<T>::type> operator+(Finaly, T&& t){
return RAII<typename std::decay<T>::type>(std::forward<T>(t));
}
#ifdef M_CATENATE_VAR_IMPL
# undef MCSF_CATENATE_VAR_IMPL
#endif
#define M_CATENATE_VAR_IMPL(prefix, suffix)\
prefix ## suffix
#ifdef M_CATENATE_VAR
# undef MCSF_CATENATE_VAR
#endif
#define M_CATENATE_VAR(prefix, suffix)\
MCSF_CATENATE_VAR_IMPL(prefix, suffix)
#ifdef M_ANONYMOUS_VAR
# undef MCSF_ANONYMOUS_VAR
#endif
#ifdef __COUNTER__
# define M_ANONYMOUS_VAR(VARIABLE)\
M_CATENATE_VAR(VARIABLE, __COUNTER__)
#else
# define M_ANONYMOUS_VAR(VARIABLE)\
M_CATENATE_VAR(VARIABLE, __LINE__)
#endif
#ifdef M_RAII
# undef M_RAII
#endif
#define M_RAII\
auto M_ANONYMOUS_VAR(RAII)\
= Finaly() + [&]
// \brief: used to explicitly mark the return value of a function
// as unused. If you are really sure you don't want to do anything
// with the return value of a function.
template<typename T>
inline void ignore_result(const T&){}
}
#endif // ___UTIL_RAII_H__
使用:
IRAII&& donePipe = MakeRAII([this, &readInfo]()
{
for each(Processor processor in readInfo.vProcessors)
{
if(nullptr != processor.first)
{ }
}
});
donePipe;