请考虑以下代码:
template<int nIndex>
int Fibonacci()
{
if constexpr (nIndex == 0) return 0;
if constexpr (nIndex == 1) return 1;
static_assert(nIndex >= 0, "Invalid index passed to Fibonacci()");
return Fibonacci<nIndex - 1>() + Fibonacci<nIndex - 2>();
}
int main()
{
Fibonacci<3>(); // 2
//Fibonacci<-1>(); // Fires assertion
return 0;
}
当我在VS2017中运行它时,编译器输出:
error C2338: Invalid index passed to Fibonacci()
note: see reference to function template instantiation 'int Fibonacci<-1>(void)' being compiled
note: see reference to function template instantiation 'int Fibonacci<1>(void)' being compiled
note: see reference to function template instantiation 'int Fibonacci<3>(void)' being compiled
这不是我的期望;我希望结果是2.我在这里错误地使用if constexpr
吗?
此外,我不理解编译器的诊断消息。
Fib(3) = Fib(2) + Fib(1)
= Fib(1) + Fib(0)
= 1 + 0 + 1
= 2
那么编译器为什么认为Fib(-1)被调用呢?
那么编译器为什么认为Fib(-1)被调用呢?
它没有;它认为它已被实例化(或更具体地说,Fibonacci<-1>
已经实例化)。
你想要的是条件实例化。只有实例化模板的语句本身由if constexpr
语句控制时才能实现:
template<int nIndex>
int Fibonacci()
{
static_assert(nIndex >= 0, "Invalid index passed to Fibonacci()");
if constexpr (nIndex == 0) return 0;
else if constexpr (nIndex == 1) return 1;
else
return Fibonacci<nIndex - 1>() + Fibonacci<nIndex - 2>();
}
如果nIndex
为0或1,那么最终return语句中的代码将不会导致模板被实例化。