Можно ли сгенерировать постоянный массив размером n

Я хочу генерировать постоянную мощность массива [501] = {1, p% MODER, p * p% MODER, p * p * p% MODER,..., p ^ 500% MODER}, из которых p является константой число.

Я знаю, что мог бы сгенерировать p^n % MODER, используя следующий код:

template<int a, int n> struct pow
{
  static const int value = a * pow<a, n-1>::value % MODER;
};
template<int a> struct pow<a, 0>
{
  static const int value = 1;
};

И это работает!

Мой вопрос, могу ли я сгенерировать массив, который я хочу?

2 ответа

Решение

Ты можешь использовать BOOST_PP_ENUM как:

#include <iostream>
#include <boost/preprocessor/repetition/enum.hpp>

#define MODER 10

template<int a, int n> struct pow
{
  static const int value = a * pow<a, n-1>::value % MODER;
};
template<int a> struct pow<a, 0>
{
  static const int value = 1;
};

#define ORDER(count, i, data) pow<data,i>::value

int main() {
  const int p = 3;
  int const a[] = { BOOST_PP_ENUM(10, ORDER, p) };
  std::size_t const n = sizeof(a)/sizeof(int);
  for(std::size_t i = 0 ; i != n ; ++i ) 
    std::cout << a[i] << "\n";
  return 0;
}

Выход:

1
3
9
7
1
3
9
7
1
3

Посмотреть онлайн демо

Линия:

int const a[] = { BOOST_PP_ENUM(10, ORDER, p) };

расширяется до этого:

int const a[] = { pow<p,0>::value, pow<p,1>::value, ...., pow<p,9>::value};

Если не n имеет верхнюю границу, я бы предположил, что это невозможно. Проверьте этот вопрос. Существуют способы сделать препроцессор похожим на Turing-complete машину, но только если вы согласитесь с тем, что размер вашего кода должен увеличиться в следующем порядке: n, что не лучше, чем размещение предварительно вычисленного массива вручную.

Важное обновление: вы должны увидеть этот вопрос тоже. Похоже, что не препроцессор, а механизм шаблонов действительно завершен по Тьюрингу (по крайней мере, может сделать рекурсию). Итак, теперь я подозреваю, что ответ - да.

Другие вопросы по тегам