将大小为编译时常量的数组初始化为单个值

Initialize array whose size is a compile-time constant to single value

本文关键字:数组 初始化 单个值 常量 小为 编译      更新时间:2023-10-16

我有一个 c 风格的数组,其大小由#define定义,可以根据编译选项进行更改,例如

#if LINUX
# define SIZE 4
#else
# define SIZE 5
#endif
static int myArr[SIZE] = { /* ??? */ };

如何将整个数组初始化为非零值,例如所有42

我不知道

C 样式数组的解决方案,尽管使用 constexpr 和 C++17 您可以使用 std::array 来做到这一点。

constexpr std::array<int, SIZE> createFilledArray (int value){
   std::array<int, SIZE> a{0};
   for (auto i = 0; i < SIZE; ++i)
       a[i] = value;
   return a;
}
static constexpr auto myArr = createFilledArray(42);

编译器资源管理器中的代码

这样做的缺点是您无法更改数组。如果从变量中删除constexpr,编译器应该能够对此进行优化。

从 C++20 开始,您可以强制初始化:

static constinit auto myArr = createFilledArray(42);

不确定提案是否已合并:请参阅持续提案

如果你坚持内置数组,你可以在函数中使用静态变量:

template <std::size_t N, std::size_t... Is>
auto arr_helper2(std::index_sequence<Is...>) -> int (&)[N]
{
    static int arr[N] = {((void)Is, 42)...};
    return arr;
}
template <std::size_t N>
auto arr_helper() -> int (&)[N]
{
    return arr_helper2<N>(std::make_index_sequence<N>{});
}
static int (&arr)[SIZE] = arr_helper<SIZE>();

例如:

int main()
{
    for (std::size_t i = 0; i < SIZE; ++i)
        std::cout << arr[i] << " ";
}

现场演示

对于仍然局限于 C++14 的可怜灵魂,这里有一个 C++14 解决方案,允许您根据函数fill填充 C 数组:

#include <iostream>
constexpr int SIZE = 5;
constexpr int fill(std::size_t index){ return 42; }
template <int INDEX = 0, int... Values>
struct Helper : Helper<INDEX + 1, Values..., fill(INDEX)> {};
template <int... Values>
struct Helper<SIZE, Values...>{
    static constexpr int table[SIZE] = { Values... };
};
template <int... Values>
constexpr int Helper<SIZE, Values...>::table[SIZE];
int main() {
    auto constexpr arr = Helper<0>::table;
    for(int i = 0; i < SIZE; ++i){
        std::cout << arr[i] << 'n';
    }
}

但是,请注意,这仅适用于整型类型。