模板元编程三元值未达到基本情况

时间:2018-08-07 07:57:01

标签: c++ templates struct ternary-operator template-meta-programming

我正在编写一个使用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语句

3 个答案:

答案 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

Live Demo on coliru

答案 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