什么你要找的是§5.19:
一个条件表达式Ë是一个核心的常量表达式,除非Ë的评价,以下抽象机的规则( 1。9)将评估以下表达式之一:
这适用于对函数调用constexpr
表达式的评估。也就是说,调用constexpr
函数将是一个'核心常量表达式',如果评估函数,即根据C++抽象机器的规则执行函数主体,则不会执行给定列表中禁止的任何事情在第5.19节中。
一个列表中的项目是:
- 功能比[...]一个constexpr功能以外的调用
所以申请到您的示例:评估表达式foo()
评估对函数incr()
的调用,该函数不是constexpr函数,这意味着表达式foo()
不是核心常量表达式。此外,由于上述适用于函数foo
的所有可能调用,第7.1.5节/5.5节中的规则开始,并且意味着您的示例程序不合格,不需要诊断,即使您从不使用实际上拨打foo()
。
由于本福格特指出一个constexpr函数可以包含非consexpr函数的调用,只要函数的具体评价实际上并不评价任何这样的函数调用(或它出现在,做一个上下文不需要一个常量表达式)。
5.19中的限制仅与表达式评估的一部分实际上最终被评估的表达式有关。
例如:
#include <iostream>
int incr(int &n) { return ++n; }
enum E {be_constexpr, not_constexpr};
constexpr int foo(E e = be_constexpr) {
int n = 0;
if (e == not_constexpr) { incr(n); }
return n;
}
int main() {
constexpr int a = foo(); // foo() is a constant expression
int b = foo(not_constexpr); // may or may not evaluate `foo(non_constexpr)` at runtime. In practice modern C++ compilers will do compile-time evaluation here even though they aren't required to.
// constexpr int c = foo(not_constexpr); // Compile error because foo(not_constexpr) is not formally a constant expression, even though modern compilers can evaluate it at compile-time.
std::cout << a << ' ' << b << '\n';
}
也许值得指出的[前面的问题](http://stackoverflow.com/q/34211688/1708801),其覆盖了许多相同的地,尽管从不同的角度。 –
@ShafikYaghmour我真的很感激你对这个新问题的评论。 – Ayrosa
请注意,你所引用的内容是必要的*但不是充分*的条件,即如果这些条件被违反,那么代码是不合格的,但是如果他们没有违反,那么代码可能会或可能不会是正确的,我们必须查看规范的其他部分。 –