template < class T >
class temp_value {
public :
temp_value(T& var) : _var(var), _original(var) {}
~temp_value() { _var = _original; }
private :
T& _var;
T _original;
temp_value(const temp_value&);
temp_value& operator=(const temp_value&);
};
好的,由于看起来这不像我想象的那样简单,这里有一个解释:
在它的构造函数中,temp_value
存储了一个变量的引用和变量原始值的副本。在它的析构函数中,它将引用的变量恢复到其原始值。因此,在构建和销毁之间对变量进行的任何操作都会在 temp_value
对象超出作用域时被重置。
像这样使用它:
void f(some_type& var)
{
temp_value<some_type> restorer(var);
g(var);
}
这里有另一种使用作用域守卫技巧的方法:
namespace detail
{
class restorer_base
{
public:
void dismiss(void) const
{
mDismissed = true;
}
protected:
restorer_base(void) :
mDismissed(false)
{}
restorer_base(const restorer_base& pOther) :
mDismissed(pOther.is_dismissed())
{
pOther.dismiss();
}
~restorer_base(void) {}
bool is_dismissed(void) const
{
return mDismissed;
}
private:
restorer_base& operator=(const restorer_base&);
mutable bool mDismissed;
};
template <typename T>
class restorer_holder : public restorer_base
{
public:
restorer_holder(T& pX) :
mX(pX),
mValue(pX)
{}
~restorer_holder(void)
{
if (!is_dismissed())
mX = mValue;
}
private:
restorer_holder& operator=(const restorer_holder&);
T& mX;
T mValue;
};
}
typedef const detail::restorer_base& restorer;
template <typename T>
detail::restorer_holder<T> store(T& pX)
{
return detail::restorer_holder<T>(pX);
}
这只是一些样板代码,但可以更清晰地使用:
#include <iostream>
template <typename T>
void print(const T& pX)
{
std::cout << pX << std::endl;
}
void foo(void)
{
double d = 10.0;
double e = 12.0;
print(d); print(e);
{
restorer f = store(d);
restorer g = store(e);
d = -5.0;
e = 3.1337;
print(d); print(e);
g.dismiss();
}
print(d); print(e);
}
int main(void)
{
foo();
int i = 5;
print(i);
{
restorer r = store(i);
i *= 123;
print(i);
}
print(i);
}
它会移除其在类中的使用能力。
以下是第三种方法,可以达到相同的效果(不会出现可能抛出析构函数的问题):
实现:
//none -- it is built into the language
使用方法:
#include <iostream>
template <typename T>
void print(const T& pX)
{
std::cout << pX << std::endl;
}
void foo(void)
{
double d = 10.0;
double e = 12.0;
print(d); print(e);
{
double f(d);
double g(e);
f = -5.0;
g = 3.1337;
print(f); print(g);
e = std::move(g);
}
print(d); print(e);
}
int main(void)
{
foo();
int i = 5;
print(i);
{
int r(i);
r *= 123;
print(r);
}
print(i);
}
c.swap(C())
来清空容器不是更好吗? - Alexandre C.