我正在编写一个使用TMP来计算第N个斐波那契数的简单测试程序。我已经找到了许多方法可以做到这一点,但我只是在尝试多种方法来加深我的理解。我遇到问题的方式是这样的:
template<int A>
struct fib
{
static const bool value = (A<2);
static const int num = (value?A:(fib<A-1>::num + fib<A-2>::num));
};
我收到的错误消息是:
error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum) instantiating 'fib<-1796>::value'|
我尝试将许多值替换为三元组的“ false”字段,以使用它并查看其作用。我仍然不明白为什么这行不通。谁能帮助我,告诉我为什么?谢谢。
编辑:我的猜测是,编译器可能会在检查值是否为true或false之前对三元数的T / F字段进行评估,但是我不确定,因为那不是if语句应该如何处理的完全可以工作,而这些应该可以粗略地模拟if语句
答案 0 :(得分:2)
我必须承认,我对模板编程的经验不足。但是在OP的情况下,一个简单的解决方案是模板专门化。
示例代码:
#include <iostream>
template<int A>
struct fib
{
static const int num = fib<A-1>::num + fib<A-2>::num;
};
template<>
struct fib<1>
{
static const int num = 1;
};
template<>
struct fib<2>
{
static const int num = 1;
};
int main()
{
fib<10> fib10;
std::cout << "fib<10>: " << fib10.num << '\n';
return 0;
}
输出:
fib<10>: 55
答案 1 :(得分:1)
以更直接的方式编写此代码的一种方法是使用if constexpr
。与常规if
(以及三元运算符)不同,未采用分支中的模板不会被实例化。
template <int n>
struct fib {
constexpr static int eval() {
if constexpr (n < 2)
return n;
else
return fib<n-1>::eval() + fib<n-2>::eval();
}
};
当然,一旦有了if constexpr
,您实际上就不需要模板来制作这种类型的编译时函数。一个constexpr
非模板函数就可以了。这只是该技术的一个说明。
答案 2 :(得分:0)
我的原始帖子的第一条评论是正确的答案。作者是(n.m.)。在三元组的两个字段中都评估模板类型的实例化,而对象实例化本身则不。为了解决这个问题,我将研究std :: condiditional或std :: enable_if