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

Why does this multiply template code cause overflow?

本文关键字:代码 溢出 为什么      更新时间:2023-10-16

我在这里有一个模板,它像这样相乘:

  • 如果我传入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> { };

我在这里做错了什么?

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

所以跳过它:

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

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

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

在实例化中,Value自身乘以5次
2 * 2 -> 4,4 * 4 -> 16,16 * 16 -> 256,256 * 256 -> 65536和65536 * 65536 -> overflow
如果您想在第四步停止,那么您需要使用multiply_n_times<2, 4>或为Count = 1提供专门化,而不是Count = 0

@user2040251有正确的答案,您的乘法导致int值溢出。更一般地说,对于Value = vCount=n的初始实例化,您可以期望达到v^(2^n)。如果您将代码更改为在Count=1处停止,那么您将到达v^(2^(n-1))。