Шаблон метапрограммирования рекурсии вверх лимитов?

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

#include <iostream>

using namespace std;

template<int N>
class Sum
{
public:
enum {value = N + Sum<N-1>::value };
};

template<>
class Sum<0>
{
public:
enum {value = 0};
};int main()
{
cout << Sum<501>::value << endl;
}

Интересная вещь:

  • Когда я печатаю сумму<500> и ниже, работает нормально
  • Когда дело доходит до суммы<501>, компиляция не удалась с:

    sum.cpp: 9: создается из Sum<500>' sum.cpp:9: instantiated
    from
    сумма<501> ‘sum.cpp: 22: создан здесь

    sum.cpp: 9: ошибка: неполный тип Sum<1>' used in nested name
    specifier sum.cpp:9: error: enumerator value for
    значение ‘не целое число
    постоянная

  • сумма<501> сообщит об ошибке суммы<1>, сумма<502> сообщит об ошибке суммы<2>, разница всегда 2, мне кажется, у компилятора есть лимит ресурсов 500.

Есть идеи по этому поводу? и есть ли способ преодолеть эти ограничения?

Благодарю.

Редактировать:
Спасибо, ребята, дело не в алгоритме, а в ограничении компилятора — я знаю, что есть простой способ получить сумму 🙂

Edit2:

  • Используйте gcc 4.6 +, сообщение об ошибке гораздо более полезно

    sum.cpp: 9: 14: ошибка: глубина создания шаблона превышает максимум
    1024 (используйте -ftemplate-глубина = чтобы увеличить максимум)
    Sum Сумма класса<1> ’sum.cpp: 9: 14: рекурсивно создается из
    «Sum<1024> ’sum.cpp: 9: 14: создается из‘ Sum<1025>»
    sum.cpp: 22: 22: создается отсюда

так что да, используйте ftemplate-глубина — правильный путь. Но как насчет окон? верхний предел для VC9.0 равен 499, и, похоже, нет возможности установить глубину шаблона, см. Вот

9

Решение

Если вы используете GCC, вы можете установить глубину рекурсии шаблона с помощью -ftemplate-depth=X, где X Требуемая глубина:

g++ ...... -ftemplate-depth=750

Имейте в виду, что это не просто предел, который вы можете установить произвольно высоким. В какой-то момент вы столкнетесь с ОС и аппаратными ограничениями.

Что касается вашей действительной функции суммы, существует хорошо известное аналитическое решение для суммы первых N натуральных чисел.

8

Другие решения

Приложение B определяет рекомендуемые минимальные пределы; за рекурсивно вложенные шаблоны рекомендуемый минимальный предел — 1024. Похоже, что ваша реализация имеет ограничение 500; это по-прежнему соответствует требованиям, поскольку рекомендуемые минимальные ограничения являются лишь ориентировочными.

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

Самое простое решение — использовать нерекурсивный алгоритм; в твоем случае,

template<int N>
class Sum
{
public:
enum {value = N * (N + 1) / 2 };
};
11

По вопросам рекламы [email protected]