【发布时间】:2020-02-22 14:46:45
【问题描述】:
我正在寻找一种方便有效的方法来初始化函数模板中的静态数组。例如,假设我们有一个这样的函数:
template <size_t windowSize>
int process_signal(int currentSignal)
{
// incorrect: inits only 3 elements; want to set all values to -1
static std::array<int, windowSize> window = { -1, -1, -1 };
// do something...
}
这样我只能用 -1 初始化前 3 个元素,但不能全部初始化。
到目前为止,我提出的最佳解决方案是使用 constexpr 函数进行编译时初始化:
template <size_t sz, int value>
constexpr std::array<int, sz> init_array()
{
std::array<int, sz> arr{};
//arr.fill(-1); // will be constexpr since C++20
// operator [] is constexpr in C++17
for (int i = 0; i < sz; ++i)
arr[i] = value;
return arr;
}
template <size_t windowSize>
int process_signal(int currentSignal)
{
// works fine, but extra variable needed
constexpr static std::array<int, windowSize> init_value = init_array<windowSize, -1>();
static std::array<int, windowSize> window = init_value;
// window will be updated...
}
这样我可以在编译时初始化一次数组。但是,它需要一个额外的constexpr 变量(在我的情况下为init_value)来绑定init_array() 函数的结果。如果我在没有它的情况下尝试相同的操作,init_array() 将作为普通函数调用(因此初始化不再是编译时):
template <size_t windowSize>
int process_signal(int currentSignal)
{
// no longer compile-time in MSVC2019
static std::array<int, windowSize> window = init_array<windowSize, -1>();
// window will be updated...
}
如果没有额外的constexpr 变量,是否可以做同样的事情?或者,也许它只是特定于我的编译器(MSVC 2019)?
【问题讨论】:
-
你可以使用模板参数包扩展,这里是some inspiration(方法3)。
-
-> This answer
-
@zett42 在这个问题中,我想强调使用 constexpr 函数初始化普通变量与 MSVC 编译器中的 constexpr 变量之间的区别。
标签: c++ visual-c++ c++17