2017-02-26 89 views
1

我想将一个更通用的const输入参数传递给斐波纳契的constexpr实现。当我用int替换模板参数时,事情又是一片混乱。模板参数constexpr

#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

输入
+0

您可以解决像这样,使其工作:'如果(N <= 1)返回牛逼{1 };返回fib_ce ...'。 –

+0

我想这是一个问题,因为它评估条件的两面。 –

回答

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. 我们也有规则:

    一旦未丢弃返回语句已在函数中看到,但是,从该语句推导出的返回类型可用于函数的其余部分,包括其他返回 s tatements。

    所以我们可以使用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 
        } 
    } 
    
3

好吧,我想我找到了答案,需要避免auto,并让编译器在这里返回类型。以下工作精细:

#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"; 
}