#c
#c
Вопрос:
У меня здесь есть этот шаблон, который умножает числа следующим образом:
- Если я передам
2
и5
в качестве аргументов шаблона, он сгенерирует 5 чисел, умноженных на себя, начиная с2
. multiply_n_times<2, 5>
должно быть равноpack<2, 4, 16, 256>
Это то, что я пробовал
template<int Value, int Count, int... Is>
struct multiply_n_times : multiply_n_times<Value*Value, Count-1, Is..., Value> { };
template<int Value, int... Is>
struct multiply_n_times<Value, 0, Is...> : pack<Is...> { };
И когда я создаю его экземпляр, я получаю эту ошибку:
main.cpp: In instantiation of 'struct multiply_n_times<65536, 1, 2, 4, 16, 256>':
main.cpp:15:8: recursively required from 'struct multiply_n_times<4, 4, 2>'
main.cpp:15:8: required from 'struct multiply_n_times<2, 5>'
main.cpp:39:17: required from here`
main.cpp:15:8: error: overflow in constant expression [-fpermissive]
struct multiply_n_times : multiply_n_times<Value*Value, Count-1, Is..., Value> { };
Что я здесь сделал не так?
Ответ №1:
Последняя рекурсия, в которой отбрасывается первый аргумент, имеет переполнение.
Так что пропустите это:
template<int Value, int... Is>
struct multiply_n_times<Value, 1, Is...> :
pack<Is..., Value>
{ };
теперь мы никогда не вычисляем a Value*Value
, который мы не будем использовать.
Оставьте 0
специализацию, если вам нужен 0
список квадратов длины.
Комментарии:
1. Спасибо. Знаете ли вы, где я могу стать лучше в ТМП?
Ответ №2:
При создании экземпляра Value
умножается сам на себя в 5 раз
2 * 2 -> 4, 4 * 4 -> 16, 16 * 16 -> 256, 256 * 256 -> 65536 и 65536 * 65536 -> переполнение.
Если вы хотите остановиться на 4 — м шаге , то вам нужно либо использовать multiply_n_times<2, 4>
, либо предоставить специализацию для Count = 1
, not Count = 0
.
Ответ №3:
@user2040251 имеет правильный ответ, ваше умножение вызывает переполнение ваших значений int. Чтобы быть немного более общим, вы можете ожидать, что для первоначального создания экземпляра с Value = v
помощью and Count=n
вы достигнете чисел до v ^ (2 ^ n) . Если вы измените свой код на stop at Count=1
, то вместо этого вы достигнете v ^(2 ^ (n-1)) .