Reputation: 21548
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
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
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] << " ";
}
Upvotes: 3
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);
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