使用 C++17 填充 constexpr 数组
populating a constexpr array using C++17
我正在尝试通过以下方式使用 C++17
初始化 constexpr
数组:
template <size_t N>
struct CStr
{
static constexpr std::array<int, N> getArr()
{
std::array<int, N> a;
for (auto idx = 0; idx < a.size(); ++idx)
{
a[idx] = idx * idx;
}
return a;
}
static constexpr auto arr { getArr()};
};
int main()
{
for (const auto &el : CStr<10>::arr)
{
std::cout << el << std::endl;
}
}
然而,这会导致以下关于 getArr
不是 constexpr
函数的编译错误。谁能帮忙解释一下为什么?
<source>: In instantiation of 'constexpr const std::array<int, 10> CStr<10>::arr':
<source>:18:27: required from 'struct CStr<10>'
<source>:24:35: required from here
<source>:18:39: error: 'static constexpr std::array<int, N> CStr<N>::getArr() [with long unsigned int N = 10]' called in a constant expression
18 | static constexpr auto arr { getArr()};
| ~~~~~~^~
<source>:9:41: note: 'static constexpr std::array<int, N> CStr<N>::getArr() [with long unsigned int N = 10]' is not usable as a 'constexpr' function because:
9 | static constexpr std::array<int, N> getArr()
| ^~~~~~
<source>:12:9: error: 'goto' is not a constant expression
12 | for (auto idx = 0; idx < a.size(); ++idx)
| ^~~
Compiler returned: 1 | ^~~~~
这是 C++20 之前的 C++ 限制,请参阅 Permitting trivial default initialization in constexpr contexts:您必须在 constexpr
函数内初始化所有变量。该标准给出了以下示例:
C++17
constexpr int uninit() {
int a; // error: variable is uninitialized
return a;
}
C++20
constexpr int uninit() {
struct { int a; } s;
return s.a; // error: uninitialized read of s.a
}
请注意,初始化本身在 C++20 中是可以的。读取不确定值(在“未初始化”对象内)是不正确的。
要解决您的问题,请初始化数组或切换到 C++20:
static constexpr std::array<int, N> getArr()
{
std::array<int, N> a{}; // now initialized!
for (auto idx = 0; idx < a.size(); ++idx)
{
a[idx] = idx * idx;
}
return a;
}
我正在尝试通过以下方式使用 C++17
初始化 constexpr
数组:
template <size_t N>
struct CStr
{
static constexpr std::array<int, N> getArr()
{
std::array<int, N> a;
for (auto idx = 0; idx < a.size(); ++idx)
{
a[idx] = idx * idx;
}
return a;
}
static constexpr auto arr { getArr()};
};
int main()
{
for (const auto &el : CStr<10>::arr)
{
std::cout << el << std::endl;
}
}
然而,这会导致以下关于 getArr
不是 constexpr
函数的编译错误。谁能帮忙解释一下为什么?
<source>: In instantiation of 'constexpr const std::array<int, 10> CStr<10>::arr':
<source>:18:27: required from 'struct CStr<10>'
<source>:24:35: required from here
<source>:18:39: error: 'static constexpr std::array<int, N> CStr<N>::getArr() [with long unsigned int N = 10]' called in a constant expression
18 | static constexpr auto arr { getArr()};
| ~~~~~~^~
<source>:9:41: note: 'static constexpr std::array<int, N> CStr<N>::getArr() [with long unsigned int N = 10]' is not usable as a 'constexpr' function because:
9 | static constexpr std::array<int, N> getArr()
| ^~~~~~
<source>:12:9: error: 'goto' is not a constant expression
12 | for (auto idx = 0; idx < a.size(); ++idx)
| ^~~
Compiler returned: 1 | ^~~~~
这是 C++20 之前的 C++ 限制,请参阅 Permitting trivial default initialization in constexpr contexts:您必须在 constexpr
函数内初始化所有变量。该标准给出了以下示例:
C++17
constexpr int uninit() {
int a; // error: variable is uninitialized
return a;
}
C++20
constexpr int uninit() {
struct { int a; } s;
return s.a; // error: uninitialized read of s.a
}
请注意,初始化本身在 C++20 中是可以的。读取不确定值(在“未初始化”对象内)是不正确的。
要解决您的问题,请初始化数组或切换到 C++20:
static constexpr std::array<int, N> getArr()
{
std::array<int, N> a{}; // now initialized!
for (auto idx = 0; idx < a.size(); ++idx)
{
a[idx] = idx * idx;
}
return a;
}