Вопрос

Я использую макросы для кодирования развернутых циклов следующим образом: (глупый пример)

#define foreach_small_prime(p, instr) {   \
  int p;                                  \
  p = 2; instr;                           \
  p = 3; instr;                           \
  p = 5; instr;                           \
  p = 7; instr;                           \
}

foreach_small_prime(pp, cout << pp);

int sum = 0;
foreach_small_prime(pp, {
  sum += pp;
  if (sum >= 10) cout << sum << endl;
});

Но в некоторых случаях я мог бы использовать для конструкции:

#define foreach_small_even(ii) for(int ii = 0; ii < 20; ii += 2)

int sum = 0;
foreach_small_even(pp) {
  sum += pp;
  if (sum >= 10) cout << sum << endl;
}

Мне нравятся эти макросы, потому что я могу передать переменную name в качестве параметра.

Вопрос: есть ли способ определить цикл, подобный первому, в синтаксисе for-like, подобном второму макросу?

Это было полезно?

Решение

Вы можете проверить библиотеку препроцессора Boost. Это может делать все виды зацикливания вещей. Синтаксис не очень хороший, но я считаю, что он работает. Я не использовал это сам, однако.

Другие советы

У вас есть веская причина избегать использования объекта итератора? Вы должны учитывать, что ваши первые макросы вставляются в 4 раза по вашему коду INSTR ...

В противном случае просто:

#define foreach_smallprime(ii) for(int ii = 0; ii <= 7; ii = next_prime(ii) )

с next_prime (ii) , определенным в том же файле, что и макрос.

  

Вопрос: есть ли способ определить цикл, подобный первому, в синтаксисе for-like, подобном второму макросу?

Я полагаю, у вас относительно небольшой рабочий набор простых чисел, поэтому создание поиска для простых чисел не должно быть слишком хлопотным. Если вам нужно сгенерировать больший список простых чисел, я уверен, что в библиотеке Boost есть некоторая магия метапрограммирования во время компиляции. Если вы генерируете более сложную последовательность чисел, было бы разумно превратить поиск в функцию, которая кэширует результаты по мере их генерации.

const int small_primes[MAX_SMALL_PRIMES] = {2, 3, 5, 7, 11, 13};

#define foreach_small_prime(pp) \
  for (int i = 0; i < MAX_SMALL_PRIMES; pp = small_primes[++i])

Используется как:

void f() {
  int sum = 0;
  int temp = 0;
  foreach_small_prime(temp) {
    sum += temp;
    if (sum >= 10) cout << sum << endl;
  }
}

Вероятно, вы хотите сбросить таблицу поиска и пространство имен MAX_SMALL_PRIMES, чтобы избежать беспорядка ... и использование широко используемого идентификатора 'i' в макросе, вероятно, плохой выбор. Я уверен, что есть и другие способы улучшить его, но это в основном то, что вы просите.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top