Как предварительно вычислить массив значений? - PullRequest
2 голосов
/ 07 ноября 2008

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

#include <iostream>
using namespace std;

template <int X, char Y>
struct power {
   enum { value = X * power<X,Y-1>::value };
};

template <int X>
struct power<X,1> {
   enum { value = X };
};

template <int X>
struct power<X,0> {
   enum { value = 1 };
};

int _tmain(int argc, _TCHAR* argv[])
{
   int powers_of_2[] = { power<2,0>::value, power<2,1>::value, ..., power<2,255>::value };
   cout << powers_of_2[1] << endl;
   return 0;
}

Ответы [ 6 ]

4 голосов
/ 07 ноября 2008

Если вы не планируете использовать большой целочисленный пакет, вы переполните целочисленный тип в 2 ^ 32 (или 2 ^ 64, в зависимости), но чтобы ответить на свой реальный вопрос, посмотрите эту статью в Википедии о шаблонном метапрограммировании .

1 голос
/ 11 ноября 2008

В подобных ситуациях я пишу небольшую программу, которая генерирует и записывает в файл инициализацию массива в исходном коде C ++, а затем #include этот файл. Этот метод прост и эффективен.

1 голос
/ 07 ноября 2008

Для хранения значения 2 ^ 255 потребуется 32 байта. Это не может быть проведено в int; вам нужен массив символов

typedef unsigned char BYTE32[32];
BYTE32 powers_of_2[256] =
{
  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4},
  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8},
  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16},
  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32},
  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64},
  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128},
  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0},
// :
// :
  {32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
  {64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
  {128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};
1 голос
/ 07 ноября 2008

Это именно то, для чего макрос полезен ...

0 голосов
/ 07 ноября 2008

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

Примеры полезных макросов доступны здесь: http://awgn.antifork.org/codes++/macro_template.h

0 голосов
/ 07 ноября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...