tags:

views:

131

answers:

3

I have to use a macro multiple times inside a function and the macro that needs to be used depends on a number I pass into the function.

e.g.

  function(int number) { 
    switch(number) { 
       case 0: doStuff(MACRO0); break; 
       case 1: doStuff(MACRO1); break; 
    } 
  }

The problem is: I have a lot stuff to do per switch statement with the same macro. Is there are more elegant solution then having all that stuff in the switch statement? Like passing the macro itself to the function? I have read about eval() like methods in C++ but they just don't feel right to me. Another way could be do determine into what the macro expands but I haven't found any info on this.

Oh, it's openGL actually.

+8  A: 

I would use a function object

struct Method1 {
    void operator()() { ... }
};

template<typename Method>
void function(Method m) {
    ...
    m();
    ...
}

int main() {
    function(Method1());
}
Johannes Schaub - litb
Why not just use a function pointer?
Andrei Krotkov
Because function objects using op() are faster and can be inlined. Given that he is doing OpenGL, i think speed matters.
Johannes Schaub - litb
+4  A: 

This very much depends on what MACRO1 expands to. If it's a constant you can just call the function outside of the switch or do multiple fall-through cases. If it depends on the local context then you will have to evaluate it every time.

Nikolai N Fetissov
+2  A: 

In addition to the above suggestions, often, I find using virtual inheritance can get rid of long conditionals, especially switches-over-enums type code. I'm not sure what your particular situation, so I'm not sure how applicable his will be, but let's say the above was

enum StyleID { STYLE0 = 0, STYLE1, STYLE2 /* ... */ };

void drawStyle(StyleID id) {
  switch(id) {
     case STYLE1: doDraw(MACROSTYLE1); break;
     /* ... */
  };
}

Long blocks of switches could be avoided via virtual inheritance:

class StyleInterface {
   /* some methods */
   virtual void doDraw() = 0;
};

class Style1 : public StyleInterface {
   /* concrete impl */
   virtual void doDraw() { doDraw(MACROSTYLE1); }
};

void drawStyle(StyleInterface* id) {
    id->doDraw();
}
Todd Gardner