【发布时间】:2017-12-23 18:58:11
【问题描述】:
请考虑以下代码:
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) 被调用了呢?
【问题讨论】:
-
好的,所以我在第二个
if constexpr和else和最后的return语句之前放置了一个 else 和一个else,它可以工作。但是我在这里遗漏了一些基本的东西,我认为在编译器点击第一个return之后它不会执行任何其他操作......还是我误解了if constexpr? -
if constexpr两个分支之外的代码将无条件编译,因此即使在您的代码变体中,Fibonacci<nIndex - 1>()和Fibonacci<nIndex - 2>也应编译为nIndex == 0和nIndex == 1。跨度> -
但是为什么在 'if constexpr (nIndex == 0) return 0;' 中的
return语句之后编译没有“停止”;我的意思是,我可以看到它没有,但我不明白为什么... -
我不知道这种行为背后的原因是什么。
标签: c++ templates if-statement c++17 constexpr