我想使用带有模板递归的枚举值来计算2个数字的HCF:
#include <stdio.h>
template<int x,int y,int r>
struct s{
enum{e=x%r==0 && y%r==0?r:s<x,y,r-1>::e};
};
int main(){
printf("%d\n",s<3,5,MIN(3,5)>::e);
return 0;
};
其中x和y是2个数,r是要测试的值,原理是找到一个数字来划分x和y,从x和y的min开始,然后减1,直到r的值可以将x和y分开。但是由于以下错误,此代码无法编译:
xxx.cpp:4:31: note: in instantiation of template class 's<3, 5, -252>' requested here
xxx.cpp:4:31: note: in instantiation of template class 's<3, 5, -251>' requested here
xxx.cpp:4:31: note: in instantiation of template class 's<3, 5, -250>' requested here
xxx.cpp:4:31: note: in instantiation of template class 's<3, 5, -249>' requested here
xxx.cpp:4:31: note: in instantiation of template class 's<3, 5, -248>' requested here
xxx.cpp:4:31: note: (skipping 246 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
xxx.cpp:4:31: note: in instantiation of template class 's<3, 5, -1>' requested here
xxx.cpp:4:31: note: in instantiation of template class 's<3, 5, 0>' requested here
xxx.cpp:4:31: note: in instantiation of template class 's<3, 5, 1>' requested here
xxx.cpp:4:31: note: in instantiation of template class 's<3, 5, 2>' requested here
xxx.cpp:8:19: note: in instantiation of template class 's<3, 5, 3>' requested here
printf("%d\n",s<3,5,3>::e);
^
xxx.cpp:4:31: note: use -ftemplate-depth=N to increase recursive template instantiation depth
enum{e=x%r==0 && y%r==0?r:s<x,y,r-1>::e};
^
1 error generated.
有什么问题?
答案 0 :(得分:1)
编译器输出幸运地显示了相关的实例:
xxx.cpp:4:31: note: in instantiation of template class 's<3, 5, -1>' requested here
xxx.cpp:4:31: note: in instantiation of template class 's<3, 5, 0>' requested here
xxx.cpp:4:31: note: in instantiation of template class 's<3, 5, 1>' requested here
让我们看一下实际的实例化
template<int x = 3, int y = 5, int r = 0>
struct s{
enum{e = 3%0==0 && 5%0==0 ? 0 : s<5,3,-1>::e};
};
显然,有两件事是错的:
3 % 0
是零除s<5,3,-1>
的实例化是不必要的。使用constexpr
可以很容易地解决这个问题,但让我们坚持使用模板解决方案。递归需要一个特殊情况,HCF(x,y)=1
是共同素数的特例。
template <int x, int y>
struct s<x,y,1> { enum e = 1 };
那就是说,你真的应该使用Euclid's algorithm,因为这种蛮力搜索不会像s<300,300,300>
那样简单。