为什么这个乘法模板代码会导致溢出?

时间:2014-06-22 19:13:35

标签: c++

我这里有这个模板,可以像这样增加数字:

  • 如果我传递25作为模板参数,则会生成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> { };

我在这里做错了什么?

3 个答案:

答案 0 :(得分:3)

在实例化中,Value本身乘以5倍 2 * 2 - &gt; 4,4 * 4 - > 16,16 * 16 - &gt; 256,256 * 256 - &gt; 65536和65536 * 65536 - &gt;溢出。
如果您想在第4步停止,则需要使用multiply_n_times<2, 4>或为Count = 1提供专业化,而不是Count = 0

答案 1 :(得分:3)

第一个参数被丢弃的最后一次递归有溢出。

所以跳过它:

template<int Value, int... Is>
struct multiply_n_times<Value, 1, Is...> :
  pack<Is..., Value>
{ };

现在我们从不计算我们不会使用的Value*Value

如果您需要0长度的正方形列表,请保留0专精。

答案 2 :(得分:1)

@ user2040251有正确的答案,你的乘法会导致int值溢出。为了更加通用,您可以预期,对于Value = vCount=n的初始实例化,您将达到最多v ^(2 ^ n)的数字。如果您将代码更改为停留在Count=1,则转而使用v ^(2 ^(n-1))。