Могу ли я выполнить «операторы переменных» внутри функции и без определений? - PullRequest
1 голос
/ 06 марта 2011

Я сталкиваюсь с проблемой, которую не могу понять, как ее можно решить без #defines или снижения производительности, хотя я уверен, что кто-то может указать мне на решение.

У меня есть алгоритм такого родапроизводит (большой) ряд значений.Для простоты в следующем я притворяюсь, что это цикл for в цикле for, хотя в моем коде он более сложный, чем этот.

В ядре цикла мне нужно выполнять вычисления с производимыми значениями.,Хотя алгоритм значений остается неизменным, расчеты различаются.

В общем, у меня есть следующее:

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
  }}
}

Итак, единственная часть, которую мне нужно изменить, это

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

Итак, чтобы решить эту проблему, я мог бы создать абстрактный базовый класс:

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

и извлечь из него «вызываемый» класс:

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;
    }
  }
};

Затем я могу передать экземпляр класса «алгоритму» следующим образом:

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);

В моем случае я получаю снижение производительности, потому что происходит косвенный вызов через таблицу виртуальных функций.Так что я думал об обходе этого.Это возможно с двумя #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

Хотя это, безусловно, работает, я не на 100% доволен этим, потому что мне не обязательно нравится # define.

Итак, мой вопрос:Есть ли лучший способ для того, чего я хочу достичь?

Ответы [ 2 ]

4 голосов
/ 06 марта 2011

Функторы:

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());
}

Они лучше всего передают функции как объекты. STL использует их много! Если вам нужна безопасность типов, вы даже можете использовать Boost.Function или C ++ 0x std::function.

1 голос
/ 06 марта 2011

Почему бы не сделать вашу общую функцию шаблоном и передать функциональный объект:

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
         }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...