Инициализировать массив, размер которого является константой времени компиляции, в одно значение - PullRequest
7 голосов
/ 30 мая 2019

У меня есть массив в стиле c, размер которого определяется #define и может меняться в зависимости от параметров компиляции, например,

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

Как я могу инициализировать весь массив ненулевым значением, например, все 42?

Ответы [ 2 ]

8 голосов
/ 30 мая 2019

Я не знаю решения для массивов в стиле 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);

Не уверен, что предложение уже объединено: см. Постоянное предложение

3 голосов
/ 30 мая 2019

Если вы настаиваете на встроенных массивах, вы можете использовать статические переменные в функциях:

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] << " ";
}

live demo

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...