Let's suppose I have a struct like this:
struct my_struct
{
int a;
int b;
}
I have a function which should set a new value for either "a" or "b". This function also requires to specify which variable to set. A typical example would be like this:
void f(int which, my_struct* s, int new_value)
{
if(which == 0)
s->a = new_value;
else
s->b = new_value;
}
For reasons I won't write here I cannot pass the pointer to a/b to f. So I cannot call f with address of my_struct::a or my_struct::b. Another thing I cannot do is to declare a vector (int vars[2]) within my_struct and pass an integer as index to f. Basically in f I need to access the variables by name.
Problem with previous example is that in the future I plan to add more variables to struct and in that case I shall remember to add more if statements to f, which is bad for portability. A thing I could do is write f as a macro, like this:
#define FUNC(which)
void f(my_struct* s, int new_value)
{
s->which = new_value;
}
and then I could call FUNC(a) or FUNC(b).
This would work but I don't like using macros. So my question is: Is there a way to achieve the same goal using templates instead of macros?
EDIT: I'll try to explain why I cannot use pointers and I need access to variable by name. Basically the structure contains the state of a system. This systems needs to "undo" its state when requested. Undo is handled using an interface called undo_token like this:
class undo_token
{
public:
void undo(my_struct* s) = 0;
};
So I cannot pass pointers to the undo method because of polymorphism (mystruct contains variables of other types as well).
When I add a new variable to the structure I generally also add a new class, like this:
class undo_a : public undo_token
{
int new_value;
public:
undo_a(int new_value) { this->new_value = new_value; }
void undo(my_struct *s) { s->a = new_value}
};
Problem is I don't know pointer to s when I create the token, so I cannot save a pointer to s::a in the constructor (which would have solved the problem). The class for "b" is the same, just I have to write "s->b" instead of s->a
Maybe this is a design problem: I need an undo token per variable type, not one per variable...
See Question&Answers more detail:os