Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ constexpr-为什么只是一个返回语句?_C++_C++11 - Fatal编程技术网

C++ constexpr-为什么只是一个返回语句?

C++ constexpr-为什么只是一个返回语句?,c++,c++11,C++,C++11,constexpr函数必须只包含一个return语句,并且在编译时应该知道每个参数: // constexpr functions use recursion rather than iteration constexpr int factorial(int n) { return n <= 1 ? 1 : (n * factorial(n-1)); } //constexpr函数使用递归而不是迭代 constexpr整数阶乘(整数n) { 返回n原因: 因为在C++11中,co

constexpr函数必须只包含一个return语句,并且在编译时应该知道每个参数:

// constexpr functions use recursion rather than iteration
constexpr int factorial(int n)
{
    return n <= 1 ? 1 : (n * factorial(n-1));
}
//constexpr函数使用递归而不是迭代
constexpr整数阶乘(整数n)
{
返回n原因:

因为在C++11中,
constexpr
是一个相当新和激进的概念,很难将一个主要的语言标准转换为一个全新的标准。保守主义规则


对于C++1y(目前针对C++14),您的示例是合法的。Tip of trunk clang已经在
-std=C++1y
标志下实现了它。

正如Andy Prowl所说,它简化了实现。这可能回答了“为什么”,但没有说明它是如何实现的

对于编译器来说,只有返回值的函数(更具体地说是没有局部变量的函数)是一种特殊情况。此函数现在由一个表达式组成:函数的AST只需要有一个根。缺少变量意味着可以在没有完整虚拟机处理的情况下计算此表达式它可以使用一个简单的树表达式求值器。由于各种原因,编译器可能已经有了这样的求值器,或者可以相对容易地创建一个(它变成了一个树简化过程)

知道表达式中只使用了
constepr
,这也提供了一个键简化。这保证了函数AST中的每个顶点都具有相同的属性,即使它是函数调用。整个
constepr
机制就是一种广义的const折叠形式。尽管它并不总是在这个时候完成在编译器中的igh级别,它确保无需付出巨大的努力即可实现(与完整的VM相比)


回到“为什么”问题。限制主要是由供应商的资源限制驱动的。按照规定,此功能不是一项巨大的工作,因此供应商可以在合理的时间内实际实现。如果没有此类限制,特别是允许局部变量,则会大大增加所需的工作量从ser的角度(我们,程序员)来看,这些限制完全是任意的。

我怀疑这只是一种使编译器实现简单的方法。因为标准是这么说的。允许使用更通用的函数会使编译器编写者的生活变得相当复杂(无论如何,C++14确实解除了一些限制)因为允许变量意味着增加许多其他(更复杂的)限制。所以他们在引入时保持简单。无论如何,有办法解决(例如,从另一个函数调用
constexpr
函数)(事实上,这就是阶乘函数所做的;如果它不是
constexpr
,它可能被写成变量和循环,即使出于某种原因它通常被用作递归的示例)“每个参数都应该在编译时已知”嗯?你是什么意思?调用参数只有在运行时才知道的
constexpr
函数是完全合法的。回答不错。
constexpr
实际上要求编译器解释它(而不是编译),因此力求简单是可以理解的。不过,如果
(适用于
constexpr
,而不仅仅适用于模板),关于哪个状态我现在还不确定。我想这也是因为另一个原因。你不能有无限循环,不合适的递归调用可以通过一个递归限制来检测。另外,对constexpr的任何更改允许更多的东西也意味着更复杂的不变量,用户必须尊重这些不变量才能在没有wan的情况下编译代码我还怀疑,实际上你还需要“证明”constexpr是有效的,并且从理论角度来看,为任意代码提供它是困难的或不可能的。
// constexpr functions use recursion rather than iteration
constexpr int factorial(int n)
{
    int a = 222; //another variable
    return n <= 1 ? 1 : (n * factorial(n-1));
}