在类作用域中,constexpr变量的初始化器是否允许引用该变量?

21

以下代码:

struct S {
    static constexpr int rolling_sum[4]{
        0,
        rolling_sum[0] + 1,
        rolling_sum[1] + 2,
        rolling_sum[2] + 3
    };
};

使用clang(版本12已测试)可以被接受,但使用gcc(版本11已测试)会因以下错误而被拒绝:

test.cpp:4:9: error: ‘rolling_sum’ was not declared in this scope
    4 |         rolling_sum[0] + 1,
      |         ^~~~~~~~~~~
test.cpp:5:9: error: ‘rolling_sum’ was not declared in this scope
    5 |         rolling_sum[1] + 2,
      |         ^~~~~~~~~~~
test.cpp:6:9: error: ‘rolling_sum’ was not declared in this scope
    6 |         rolling_sum[2] + 3
      |         ^~~~~~~~~~~

这段代码是有效的 C++ 代码吗?

我的猜测是它应该是有效的,因为 [basic.scope.pdecl] p1 规定变量的声明点就在其初始化之前,意味着变量应该在其初始化器中作用域内。但我不确定是否有其他相关问题被忽略了。


1
它在类似的测试中似乎工作正常:https://godbolt.org/z/sYY84zehh (但在实际示例中仍然不起作用,不确定原因)。看起来问题可能与在“struct”中定义数组有关。 - mediocrevegetable1
2个回答

6
你没有错过什么。这是GCC 11中报告的GCC bug 99059

您的情况也适用,因为与static inline一样,constexpr变量必须在声明点初始化。同样的查找相关错误也会影响C++14代码。


5

根据您引用的 [basic.scope.pdecl]/1,允许这样做(因为 /3 和 forward 都没有拒绝它),因此您的程序是良好的。

我们可以研究一个类似的例子,对于这个例子,GCC 令人困惑地拒绝了其中的一部分:

struct S {
    static constexpr int x{42};
    static constexpr int y[2]{
        S::x,        // #1 GCC: OK
        S::y[0] + 1  // #2 GCC: error: incomplete type 'S' used in nested name specifier
    };
};

在 #2 处出现了一个错误信息,如果不是因为 #1 被拒绝而无效,这个错误信息应该被应用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接