在以下示例中:
//Case 1
constexpr int doSomethingMore(int x)
{
return x + 1;
}
//Case 2
constexpr int doSomething(int x)
{
return ++x;
}
int main()
{}
输出:
prog.cpp:在函数‘constexpr int doSomething(int)’中:
prog.cpp:12:1:错误:表达式“++ x”不是常量表达式
为什么情况1允许而情况2不允许?
情况 1 不修改任何内容,情况 2 修改变量。对我来说似乎很明显!
修改变量要求它不是常量,您需要具有可变状态,并且表达式
++x
会修改该状态。由于 constexpr
函数可以在编译时求值,因此实际上没有任何“变量”需要修改,因为没有代码正在执行,因为我们还没有处于运行时。
正如其他人所说,C++14 允许
constexpr
函数修改其局部变量,从而允许更有趣的事情,例如 for
循环。那里仍然没有真正的“变量”,因此编译器需要在编译时充当简化的解释器,并允许在编译时操作有限形式的本地状态。与更为有限的 C++11 规则相比,这是一个相当重大的变化。
你的论点确实是有效的,从
constexpr
的精神/技术角度来说,x+1
和++x
是相同的。其中 x
是函数的局部变量。因此在任何情况下都应该没有错误。
此问题现已在 C++14 中得到修复。这是分叉的代码,可以与 C++14 很好地编译。
常量表达式在第 5 条的最后几页中定义。
作为粗略的描述,它们是无副作用的表达式,可以在编译时(翻译期间)进行评估。围绕它们的规则是根据这一原则创建的。