【发布时间】:2020-04-26 23:11:08
【问题描述】:
下面的代码合法吗?
template <int N>
class foo {
public:
constexpr foo()
{
for (int i = 0; i < N; ++i) {
v_[i] = i;
}
}
private:
int v_[N];
};
constexpr foo<5> bar;
Clang 接受它,但 GCC 和 MSVC 拒绝它。
GCC 的错误是:
main.cpp:15:18: error: 'constexpr foo<N>::foo() [with int N = 5]' called in a constant expression
15 | constexpr foo<5> bar;
| ^~~
main.cpp:4:15: note: 'constexpr foo<N>::foo() [with int N = 5]' is not usable as a 'constexpr' function because:
4 | constexpr foo()
| ^~~
main.cpp:4:15: error: member 'foo<5>::v_' must be initialized by mem-initializer in 'constexpr' constructor
main.cpp:12:9: note: declared here
12 | int v_[N];
| ^~
如果这种代码没问题,我可以少用index_sequences。
【问题讨论】:
-
Gcc10 也接受它。
-
你能从 MSVC 抄录错误吗?
-
...还有 GCC。
-
@songyuanyao - g++10 接受它编译 C++20;拒绝它编译 C++17 或更早版本;重点似乎应该在初始化列表中初始化
_v,直到 C++17。也许在 C++20 中有所改变。 -
@Evg 这实际上很有趣,因为它可能表明 Clang 使用它的“意识”,即静态存储持续时间对象被归零以说“好吧,这个对象可能已经默认初始化,但读取从其
int成员将永远不会有未定义的行为”。我想知道 GCC not 这样做是否合规,或者相反......
标签: c++ template-meta-programming constexpr compile-time-constant