Tutorial :Using Many Arguments Without Duplicating Code



Question:

Is there a way to use each of the arguments in this function in sequence without duplicating code? For example, the first time through the loop I'd like to use R, the next time I'd like to use L, etc. valuestruct is set up in the same order as the arguments, so the button method will return the equivalent bool I need for currentbutton according to int i. If there's a better method to accomplish the same thing that's ok too.

int valuex=0;    void SetValue(bool &R,bool &L,bool &D,bool &U,bool &T,bool &S,bool &B,bool &A,bool &Y,bool &X,bool &W,bool &E,bool &G, bool &F) {            bool value[4] = {true, false, true, false};          bool currentbutton;            for (int i=0; i < 12; i++) {              currentbutton=valuestruct.button(i);                if(currentbutton) {                  "I want to grab each argument in sequence here"=value[valuex];                  valuex++;                  if(valuex>ARRAYSIZE(value))                      valuex=0;              }          }      }  


Solution:1

If you really do insist on this function prototype (and not following the other suggestions here of passing an array or a list - which are better), you can use something like that -

void SetValue(bool &R,bool &L,bool &D,bool &U,bool &T,bool &S,bool &B,bool &A,bool &Y,bool &X,bool &W,bool &E,bool &G, bool &F)  {     bool* Bools[] = { &R, &L, &D, &U, &T, &S, &B, &A, &Y, &X, &W, &E, &G, &F };       // *Bools[i] can be used to access the ith element.       // Print the 4th element.     std::cout << *Bools[3];       // Change the value of the 5th.     *Bools[4] = true;  }  

By the way, if you don't really need to change the passed values, you should not pass them by reference. Passing a bool by reference only wastes time and space. It would also make the code here a bit less cluttered.


Solution:2

Have you considered using a bool array? :) A collection is definitely the way to go. If you need to retain metadata for filtering or grabbing certain values, consider using a Map.


Solution:3

Or a bit field? Quick&dirty version:

int field = FLAG_R | FLAG_L    void SetValue(int fields) {      for (int i = 0; i < FLAG_COUNT; i++) {          if (fields & (1 << i)) {              // Flag #i is set          }      }  }  

EDIT

Btw, passing bools as reference is useless if you're not changing the value. The pointer used for the reference is possibly longer than the type holding the bool itself.


Solution:4

You could use the variable argument support, since you have a fixed number of arguments you know how much to loop for. IIRC it does not actually require that the function have variable arguments.

va_list args;                                                                                                       va_start(args,R);  // your code here...  va_end();  

Forgive me if this is off base... it's been some years since I actively coded C.


Solution:5

I'd add this to hexagon's answer but I can't edit posts yet.

int valuex=0;    void SetValue(bool &R,bool &L,bool &D,bool &U,bool &T,bool &S,bool &B,bool &A               ,bool &Y,bool &X,bool &W,bool &E,bool &G, bool &F)   {      bool* bools[] = { &R, &L, &D, &U, &T, &S, &B, &A, &Y, &X, &W, &E, &G, &F };      bool value[4] = {true, false, true, false};      bool currentbutton;        for (int i=0; i<12 && i < ARRAYSIZE(bools); i++) {              currentbutton=valuestruct.button(i);                if(currentbutton) {                      *bools[i]=value[valuex];                      valuex++;                      if(valuex>ARRAYSIZE(value))                              valuex=0;              }      }  }  

Though I don't understand where it is thought you will only read the value of the bools, you just may not set all of them.


Solution:6

You could put the arguments to an array and pass the array instead. Depending on what the calling code is this could lead to less code.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »