简体   繁体   English

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

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

I have a c-style array whose size is defined by a #define and can change based on compiling options, eg我有一个 c 样式的数组,其大小由#define定义,并且可以根据编译选项进行更改,例如

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

How can I initialize the whole array to a non-zero value, for example all 42 ?如何将整个数组初始化为非零值,例如 all 42

I don't know a solution for C-style arrays, though with constexpr and C++17 you could do this with std::array .我不知道 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);

Code at compiler explorer编译器资源管理器中的代码

The disadvantage of this is that you can't change the array.这样做的缺点是您无法更改数组。 If you remove the constexpr from the variable, your compiler should be able to optimize this.如果您从变量中删除constexpr ,您的编译器应该能够对此进行优化。

From C++20 on, you can force the initialization:从 C++20 开始,您可以强制初始化:

static constinit auto myArr = createFilledArray(42);

Not sure if the proposal is already merged in: seeconstinit proposal不确定提案是否已合并:请参阅constinit 提案

If you insist on builtin arrays, you can use static variables in functions:如果你坚持使用内置数组,你可以在函数中使用静态变量:

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>();

For example:例如:

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

live demo现场演示

For the poor souls who are still limited to C++14, here's a C++14 solution that allows you to fill the C array according to a function fill :对于仍然受限于 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';
    }
}

However, note that this only works for integral types.但是,请注意,这仅适用于整数类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM