c++ - 嵌套 conexpr 函数错误

标签 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
}

错误信息是:x must be initailized by a constant expression

但是从行 (ok) 可以看出 bar() 是 constexpr。

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

constexpr int foo(const int v) {
    return bar(v);
}

没关系!

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

最佳答案

修复是这个

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

关键字 constexpr 意味着两个非常不同的东西。 constexpr 变量必须在编译时求值,而 constexpr 函数必须可以在编译时求值。没有什么可以阻止您在运行时调用 foo 。这意味着……

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

如果在编译时调用 foo,则不会存储 x,它是编译器中的临时变量,因此将其设为 constexpr 没有任何意义。

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

关于c++ - 嵌套 conexpr 函数错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40690468/

相关文章:

c++ - 当我在 C++ 中派生一个类时,它是否创建一个基类的对象并将其作为我的成员变量存储在派生类中?

c++ - 我可以从 constexpr 函数返回一个可选值吗?

c++ - constexpr if 的等效三元运算符?

c++ - 如果基类包含数组成员,则派生类的构造函数不能是 constexpr

c++ - clang 3.3 和 GCC 4.7 const v 的 constexpr

c++ - 变量上的 `const constexpr` 是多余的吗?

java - 在 OpenCv4Android 中存储测试数据

c++ - 如何使我的自定义类型与 "range-based for loops"一起使用?

c++ - Windows 7 中的 COleTemplateServer::RegisterAll() 会发生什么

C++:以对角线方式处理二维数组元素