开发者

Can I execute a "variable statements" within a function and without defines?

I am facing a problem that I cannot see how it is solvable without #defines or incurring a performance impact although I am sure that someone can point me to a solution.

I have an algorithm that sort of produces a (large) series of values. For simplicity's sake, in the following I pretend it's a for loop in a for l开发者_如何转开发oop, although in my code it's more complex than that.

In the core of the loop I need to do calculations with the values being produced. Although the algorithm for the values stays the same, the calculations vary.

So basically, what I have is:

void normal() {

  // "Algorithm" producing numbers (x and y):    
  for (int x=0 ; x<1000 ; x++) {
  for (int y=0 ; y<1000 ; y++) {
    // Calculation with numbers being produced:
    if ( x+y == 800 && y > 790) {
         std::cout << x << ", " << y << std::endl;
    }
    // end of calculation
  }}
}

So, the only part I need to change is

if ( x+y == 800 && y > 790) {
     std::cout << x << ", " << y << std::endl;
}

So, in order to solve that, I could construct an abstract base class:

class inner_0 {
   public: 
   virtual void call(int x, int y) = 0;
 };

and derive a "callable" class from it:

class inner : public inner_0 {
  public: 
  virtual void call(int x, int y) {
    if ( x+y == 800 && y > 790) {
         std::cout << x << ", " << y << std::endl;
    }
  }
};

I can then pass an instance of the class to the "algorithm" like so:

void O(inner i) {

  for (int x=0 ; x<1000 ; x++) {
  for (int y=0 ; y<1000 ; y++) {
      i.call(x,y);
  }}
}

// somewhere else....

inner I;
O(I);

In my case, I incur a performance hit because there is an indirect call via virtual function table. So I was thinking about a way around it. It's possible with two #defines:

#define OUTER                           \
        for (int x=0 ; x<1000 ; x++) {  \
        for (int y=0 ; y<1000 ; y++) {  \
             INNER                      \
        }}

//  later...
#define INNER                 \
if (x + y == 800 && y > 790)  \
    std::cout << x << ", " << y << std::endl;

OUTER

While this certainly works, I am not 100% happy with it because I don't necessarly like #defines.

So, my question: is there a better way for what I want to achieve?


Functors :

struct Caller
{
    void operator()(int x, int y)
    {
        if ( x+y == 800 && y > 790)
            std::cout << x << ", " << y << std::endl;
    }   
};

template <typename T>
void your_algorithm(T foo)
{
    for (int x=0 ; x<1000 ; x++)
        for (int y=0 ; y<1000 ; y++)
            foo(x, y);
}

int main()
{
    your_algorithm(Caller());
}

They are the best to pass functions as objects. STL uses them a lot ! It you want type-safety, you can even use Boost.Function or the C++0x std::function.


Why not make your overall function a template, and pass in a function object:

template <type T> workOnGeneratedNumbers(T functor){
    // "Algorithm" producing numbers (x and y):    
    for (int x=0 ; x<1000 ; x++) {
        for (int y=0 ; y<1000 ; y++) {
            // Calculation with numbers being produced:
            functor(x,y);
            // end of calculation
         }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜