возможно ли рекурсивное явное создание шаблона? - PullRequest
6 голосов
/ 13 сентября 2011

Учитывая шаблон, подобный

template<int dim> class Point { ... };

, этот шаблон может быть явно создан, например,

template class Point<0>;
template class Point<1>;
template class Point<2>;
template class Point<3>;

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

template class RecursiveInstantiate<Point, 3>;

, где RecursiveInstantiate<T, i> создаст экземпляр T<i>, T<i-1>, ..., T<0>.Можно ли как-то создать такой класс RecursiveInstantiate?Если это невозможно, знаете ли вы способ сделать это с препроцессором?

На самом деле я заинтересован в обобщении этого для классов с несколькими параметрами шаблона, такими как Node<int i1,int i2,int i3> для всех комбинаций i1, i2,i3 в {0,1,2,3}.Но я надеюсь, что смогу решить эту вторую часть самостоятельно.

Любой совет, а также объяснение, почему невозможно то, чего я хочу достичь, приветствуется.


Обновление: спасибо за ваши комментарии.Теперь я вижу более ясно, где проблема на самом деле.Строка

template class Point<3>;

создает экземпляр шаблона и экспортирует его символы в объектный файл.Создание экземпляра формы

template class RecursiveInstantiate<Point, 3>;

может создавать экземпляры классов class Point<3>, class Point<2>, .... По-видимому, это происходит только локально.Шаблоны не экспортируются в объектный файл.Возможно, мне придется искать решение с использованием препроцессора.

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

Примечание: Я пытаюсь это на Linux с g ++ / clang в качестве компиляторов.

Ответы [ 2 ]

9 голосов
/ 13 сентября 2011

Вы можете создать небольшой класс Instantiator:

template <unsigned int N> struct Instantiator
{
  Point<N> p;
  Instantiator<N-1> i;
};

template <> struct Instantiator<0>
{
  Point<0> p;
};

Затем просто добавьте один явный экземпляр: template struct Instantiator<81>;

Вы можете расширить эту идею лексикографически для любогочисло целых параметров.


Как говорит @ Георг, давайте сделаем это обобщенно:

template <template <unsigned int> class T, unsigned int N> struct Instantiator
{
  T<N> t;
  Instantiator<T, N-1> i;
};

template <template <unsigned int> class T> struct Instantiator<T, 0>
{
  T<0> t;
};

template struct Instantiator<Point, 82>;
4 голосов
/ 13 сентября 2011

Вы можете сделать это так:

template<int dim> struct Point {
    static const int val = dim;
    Point<dim - 1> p;
};

template<> struct Point<0> { ... };

Это создает специализацию шаблона для параметра шаблона, когда он равен 0, поэтому рекурсия на этом останавливается, и когда вы создаете экземпляр такого типа:

Point<4>

Он создается от Point<4> до Point<0>. Тогда вы можете сделать

Point<4>::val

для доступа к значению этого конкретного.

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