嵌套contexpr函数错误

wim*_*aan 5 c++ constexpr

以下代码不能用g ++/clang ++编译.

constexpr int bar(int v) {
    if (v > 0){
        return v * 2;
    }
    return 2;
}

constexpr int foo(const int v) {
    constexpr auto x =  bar(v); // error
    return v;
}

int main() {
    constexpr auto a = foo(1);
    constexpr auto b = bar(1); // ok
}
Run Code Online (Sandbox Code Playgroud)

错误消息是:x必须由常量表达式初始化

但是从行(ok)你看到bar()是constexpr.

如果我将foo()的主体改为

constexpr int foo(const int v) {
    return bar(v);
}
Run Code Online (Sandbox Code Playgroud)

没关系!

我不清楚,为什么第一种形式不可能.我使用g ++ - 6.2.1,g ++ - 7.0.0和clang ++ - 3.9.0

Tim*_*Tim 5

修复就是这个

constexpr int foo(const int v) {
    auto x =  bar(v);
    return v;
}
Run Code Online (Sandbox Code Playgroud)

关键字constexpr意味着两个非常不同的东西.必须在编译时评估constexpr变量,而在编译时必须能够评估constexpr函数.没有什么可以阻止你在运行时调用foo.这意味着...

  1. 论证v不一定是constexpr.
  2. 当用b调用bar时,答案可能不是constexpr.
  3. 结果不能存储在constexpr变量中,因为它可能不是constexpr.

如果在编译时调用foo然后不存储x,则它是编译器中的临时变量,因此使其成为constexpr没有任何意义.

只有在运行时评估foo时,x的constexpr'ness才有意义,在这种情况下,它不能是constexpr,这会导致错误.