constexpr的模板参数

时间:2017-02-26 09:32:02

标签: c++ c++11 templates c++14 constexpr

我正在尝试传递更多"泛型" const输入参数到fibonacci的constexpr实现。当我用int替换模板参数时,事情又变得很糟糕了。

#include<iostream>
template <typename T>
constexpr auto fib_ce(T n) {
   return (n>1) ? fib_ce(n-1)+fib_ce(n-2) : 1;
}

int main() {
   std::cout<<fib_ce(4)<<"\n";
}

这是我得到的错误:

g++ -std=c++14 -o constexpr_fib constexpr_fib.cpp 
constexpr_fib.cpp:4:19: fatal error: recursive template instantiation exceeded maximum depth of 256
   return (n>1) ? fib_ce(n-1)+fib_ce(n-2) : 1;

              ^

如何为constexpr提供模板参数,该参数可以为此constexpr提取long,int,unsigned long等输入

2 个答案:

答案 0 :(得分:3)

好吧,我想我找到了答案,需要避免自动并让编译器在这里运行返回类型。以下工作正常:

#include<iostream>
template <typename T>
constexpr T fib_ce(T n) {
   return (n>1) ? fib_ce(n-1)+fib_ce(n-2) : 1;
}

int main() {
   std::cout<<fib_ce(4)<<"\n";
}

答案 1 :(得分:3)

[dcl.spec.auto]中的规则是:

  

如果需要具有undeduced占位符类型的实体类型来确定表达式的类型,   该计划格式不正确。

这只是缩短了可能无限递归演绎的任意复杂性。但不要害怕,有办法解决这个问题:

  1. 只需使用T代替auto

    template <class T>
    constexpr T fib_ce(T n) {
        return (n>1) ? fib_ce(n-1)+fib_ce(n-2) : 1;
    }
    
  2. 我们也有规则:

      

    然而,一旦在函数中看到了非丢弃的return语句,从该语句推导出的返回类型可以在函数的其余部分中使用,包括在其他返回中   语句。

    因此我们可以使用if语句而不是条件运算符。我们只需要反转逻辑,以便具有已知类型的return语句首先出现:

    template <typename T>
    constexpr auto fib_ce(T n) {
       if (n <= 1) {
           return static_cast<T>(1);       // ok, deduced as T
       }
       else {
           return fib_ce(n-1)+fib_ce(n-2); // we already deduced T, so sticking with it
       }
    }
    
相关问题