4

根据我从这个答案中收集到的信息,constexpr如果尚未声明函数,则函数的结果不是常量表达式。令我惊讶的是以下代码片段:

constexpr int f();

constexpr int g() {
    return f();
}

constexpr int f() {
    return 42;
}

int main() {
    constexpr int i = g();
    return i;
}

这编译没有麻烦并且有效。正如我所期望的那样,将的f定义移过 main triggers 。error: 'constexpr int f()' used before its definition

我认为它可以工作,因为f在调用之前已经定义了g,因此两个调用都是常量表达式。

为什么是f()并且g()显然是常量表达式,即使f在调用时没有定义g?标准是如何描述的?

我已经在 Coliru 的 GCC 6.1.0 和 Clang 3.8.0 上对此进行了测试。

4

2 回答 2

0

constexpr在使用之前不需要定义 a 。但是,在定义之前调用它的结果是 not constexpr。因此,编译器理所当然地抱怨,因为您正在尝试使用非常constexpr量表达式初始化变量。

§5.20/p2 常量表达式 [expr.const]强调我的):

条件表达式 e 是核心常量表达式,除非按照抽象机 (1.9) 的规则对 e 的求值将求值以下表达式之一:

...

(2.3) —调用未定义的 constexpr 函数或未定义的 constexpr 构造函数;

于 2016-05-30T13:09:38.443 回答
0

正如 TC 在他的评论中所链接的,这取决于缺陷报告

根据 5.20 [expr.const] bullet 2.3,表达式是常量表达式,除非(除其他原因外)它会计算

  • 调用未定义的constexpr函数或未定义的constexpr构造函数;

constexpr 这并没有解决必须定义函数的点的问题。为了允许相互递归constexpr的函数,其意图是必须在最终导致调用的最外层评估之前定义函数,但这没有明确说明。

这清楚地表明该示例格式正确,并且只要f在调用g.

于 2016-06-02T08:33:16.020 回答