c : инициализировать constexpr std-2DArray программно

#c #multidimensional-array #c 17

#c #многомерный массив #c 17

Вопрос:

Я новичок в C и в процессе обучения. У меня есть deftype матрицы:

 using Matrix = std::array<std::array<T, COL>, ROW>;
  

Я могу инициализировать матрицу constexpr «вручную» как таковую

 constexpr Matrix<int, 2,2> mat{ {
        {{ 1,2 }},
        {{ 3, 4 } }
}};
  

Это невозможно для больших примеров ROW, COL. Вместо этого я хотел бы инициализировать его «программно» (т. Е. Через цикл или аналогичный) с помощью функции fill_entry , которая
mat[i][j] принимает значение fill_entry(i,j) и fill_entry представляет собой что-то вроде

  template<T>
constexpr T fill_entry(T This_object_has_type_T,int i , int j).
  

Каков правильный способ сделать это? Я использую C 17

Ответ №1:

Вы можете использовать немедленно вызываемый лямбда-выражение:

 constexpr auto mat = []() {
    Matrix<int, 2, 2> result{};

    int value = 1;
    for (std::size_t i = 0; i < result.size();   i) {
        for (std::size_t j = 0; j < result[0].size();   j) {
            result[i][j] = value;
              value;
        }
    }

    return resu<
}();
  

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

 template<typename T, std::size_t Rows, std::size_t Cols>
constexpr Matrix<T, Rows, Cols> create_mat() {
    Matrix<T, Rows, Cols> result{};

    int value = 1;
    for (std::size_t i = 0; i < result.size();   i) {
        for (std::size_t j = 0; j < result[0].size();   j) {
            result[i][j] = static_cast<T>(value);
              value;
        }
    }

    return resu<
}
  

и назовите его как create_mat<int, 2, 2>() .

Комментарии:

1. Спасибо. Ваше решение не работает с моим компилятором (MS visual studio), оно выдает мне ошибку при вызове create_mat, что «constexpr функция create_mat не может привести к постоянному выражению». Я обнаружил, что ваше решение работает, если я переключусь с C 17 на опцию «latest», которая, я полагаю, означает c 20. На каком компиляторе / операционной системе вы тестировали свой?

2. @Conformal Вы правы, он не компилируется с C 17 (но компилируется с C 20), причина result в том, что необходимо инициализировать значение , поэтому изменение result на result{} должно работать (оно работает на godbolt ). Я также исправил несколько опечаток в своем ответе.