NoS*_*tAl 52 c++ constexpr c++11
您可能知道,C++ 11引入了constexpr关键字.
C++ 11引入了关键字constexpr,它允许用户保证函数或对象构造函数是编译时常量.[...]这允许编译器理解并验证[函数名称]是编译时常量.
我的问题是为什么对可以声明的函数的形式有严格的限制.我理解保证功能是纯粹的愿望,但考虑到这一点:
在函数上使用constexpr会对函数的作用施加一些限制.首先,该函数必须具有非void返回类型.其次,函数体不能声明变量或定义新类型.第三,正文可能只包含声明,空语句和单个return语句.必须存在参数值,以便在参数替换后,return语句中的表达式生成常量表达式.
这意味着这个纯函数是非法的:
constexpr int maybeInCppC1Y(int a, int b)
{
if (a>0)
return a+b;
else
return a-b;
//can be written as return (a>0) ? (a+b):(a-b); but that isnt the point
}
Run Code Online (Sandbox Code Playgroud)
你也不能定义局部变量... :(所以我想知道这是一个设计决定,还是编译器吮吸来证明功能a是纯粹的?
Dan*_*ker 28
您需要编写语句而不是表达式的原因是您希望利用语句的附加功能,尤其是循环功能.但要有用,那就需要能够声明变量(也被禁止).
如果将用于循环的工具与可变变量和逻辑分支(如if语句中)结合起来,那么您就能够创建无限循环.无法确定这样的循环是否会终止(停止问题).因此,某些源会导致编译器挂起.
通过使用递归纯函数,可以导致无限递归,这可以被证明对上述循环功能具有同等的强大功能.但是,C++在编译时已经存在这个问题 - 它发生在模板扩展中 - 因此编译器必须有一个"模板堆栈深度"的开关,以便他们知道何时放弃.
所以限制似乎旨在确保这个问题(确定C++编译是否会完成)不会比现在更棘手.
Fle*_*exo 28
constexpr函数规则的设计使得编写具有任何副作用的函数是不可能的constexpr.
通过要求constexpr没有副作用,用户不可能确定实际评估的位置/时间.这很重要,因为constexpr允许函数在编译时和编译时自行决定.
如果允许副作用,那么就需要对它们被观察的顺序有一些规则.这将非常难以定义 - 甚至比static初始化订单问题更难.
用于保证这些函数无副作用的一组相对简单的规则是要求它们只是一个表达式(除此之外还有一些额外的限制).这听起来很有限,并排除了你所说的if语句.虽然这个特殊情况没有副作用,但它会在规则中引入额外的复杂性,并且假设你可以使用三元运算符编写相同的东西,或者递归地说它并不是真正的大问题.
n2235是constexpr在C++ 中提出添加的论文.它讨论了设计的合理性 - 相关引用似乎是关于析构函数的讨论,但通常相关:
原因是编译器在翻译时要编译一个常量表达式,就像任何其他内置类型的文本一样; 特别是不允许有可观察到的副作用.
有趣的是,该论文还提到,之前的提案建议编译器自动计算出哪些函数constexpr没有新的关键字,但发现这是非常复杂的,这似乎支持了我的建议,即规则设计简单.
(我怀疑论文中引用的参考文献中会有其他引用,但这涵盖了我关于没有副作用的论点的关键点)
hiv*_*ert 12
实际上,C++标准化委员会正在考虑为c ++ 14删除其中的几个约束.请参阅以下工作文件:http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3597.html
| 归档时间: |
|
| 查看次数: |
10352 次 |
| 最近记录: |