我正在尝试传递更多"泛型" 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等输入
答案 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占位符类型的实体类型来确定表达式的类型, 该计划格式不正确。
这只是缩短了可能无限递归演绎的任意复杂性。但不要害怕,有办法解决这个问题:
只需使用T
代替auto
:
template <class T>
constexpr T fib_ce(T n) {
return (n>1) ? fib_ce(n-1)+fib_ce(n-2) : 1;
}
我们也有规则:
然而,一旦在函数中看到了非丢弃的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
}
}