什麼你要找的是§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
請注意,你所引用的內容是必要的*但不是充分*的條件,即如果這些條件被違反,那麼代碼是不合格的,但是如果他們沒有違反,那麼代碼可能會或可能不會是正確的,我們必須查看規範的其他部分。 –