I want to reset multiple variables when they go out of scope.
Currently, I have a solution for 1 variable, which is similar to given in the answers here:
General way to reset a member variable to its original value using the stack?
template<typename T>
struct Context
{
T savedValue;
T& ref;
Context(T& value) : savedValue(value), ref(value) {}
~Context()
{
ref = savedValue;
}
};
#define CONCAT_(x,y) x##y
#define CONCAT(x,y) CONCAT_(x,y)
// __line__ to allow multiple
#define SAVE_CONTEXT(var) Context<decltype(var)> CONCAT(ctx, __LINE__)(var)
What I am looking for is something like this:
template<typename... Ts>
struct Context
{
std::tuple<Ts...> savedValues; // OK
T& ref; // What should be the type here?
Context(Ts... values) : {} // How ?
~Context()
{
// ?
}
};
#define SAVE_CONTEXT(...) ... // ?
If I understood the issue correctly, you could achieve the same with non-MACRO ways.
#include <tuple>
#include <utility>
template<typename... Args> class Context
{
std::tuple<Args...> mSavedValues; // for values
std::tuple<Args&...> mRefs; // for references
public:
constexpr Context(Args&... values)
: mSavedValues(values...)
, mRefs(values...)
{}
constexpr ~Context() {
// reset to the initial values
mRefs = mSavedValues;
}
};
// template "saveContext" instead of the MACRO
template<typename... Args>
constexpr Context<Args...> saveContext(Args&... values) {
return Context<Args...>(values...);
}
You would use it like this:
int main()
{
int a = 1;
float b = 2.2f;
{
auto ctx = saveContext(a, b);
a = 10;
b = 20.02f;
// a and b will be set to 10 and 20.02f
}
// a and b will be reset to their original values
// (1 and 2.2f) when going out of scope
}