Baruch
Baruch

Reputation: 21548

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, e.g.

#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?

Upvotes: 7

Views: 1456

Answers (3)

joni
joni

Reputation: 7157

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:

#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.

Upvotes: 0

L. F.
L. F.

Reputation: 20649

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

Upvotes: 3

JVApen
JVApen

Reputation: 11317

I don't know a solution for C-style arrays, though with constexpr and C++17 you could do this with 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.

From C++20 on, you can force the initialization:

static constinit auto myArr = createFilledArray(42);

Not sure if the proposal is already merged in: see constinit proposal

Upvotes: 8

Related Questions