C++, почему расширение моего шаблона привело к переполнению стека компилятора?
Я пробовал шаблонное метапрограммирование и написание функции для вычисления мощности базы, например 3^2=9
template<int N>
int Tpow(int base){return N==0?1:base*Tpow<N-1>(base);}
int main()
{
int r3=Tpow<3>(2);
return 0;
}
Всего несколько строк, но он вылетает как gcc, так и clang. Где я ошибся? Благодарю.
2 ответа
Решение: Вы должны специализировать свой шаблон для N, равного 0. Как:
template<>
int Tpow<0>(int base){return 1;}
Теперь, когда у вас есть это, вы также можете оптимизировать свой оригинальный шаблон следующим образом:
template<int N>
int Tpow(int base){return base*Tpow<N-1>(base);}
потому что вы знаете, что обрабатывать случай N равен 0.
Пояснение: Ваш компилятор в основном делает это: Он видит
int r3=Tpow<3>(2);
и делает функцию для 3 в качестве переменной шаблона, например, так
int Tpow_3(int base){return 3==0?1:base*Tpow<3-1>(base);}
а затем он должен сделать функцию для 2 в качестве переменной шаблона, например, так
int Tpow_2(int base){return 2==0?1:base*Tpow<2-1>(base);}
и это продолжается и продолжается, потому что компилятор не заботится о вашем 0==0?...
еще.
Компилятор должен скомпилировать все тело функции: он не может полагаться на троичное условное выражение для компиляции только одной стороны. Таким образом, нет никакого блока на рекурсии.
(С использованием constexpr
C++11 тоже не поможет).
Чтобы решить эту проблему, вам нужно специализировать функцию для случая N = 0.