Однострочный инициализатор для повышения.Многомассивный

StackOverflow https://stackoverflow.com/questions/8824247

  •  27-10-2019
  •  | 
  •  

Вопрос

У меня есть n-мерный импульс.Многомерный массив я инициализирую следующим образом:

const int n=3, size=4; //# of dimensions and size of one dimension
boost::multi_array<char,n> arr;
boost::array<size_t,n> extents; //size of each dimension
extents.assign(size); //assign size to each dimension -> {{4, 4, 4}}
arr.resize(extents);

Итак, у меня есть 4 строки кода для получения MultiArray, но я бы хотел сделать это в одной строке.Есть ли какой-нибудь простой способ сгенерировать многомассив с n измерениями, каждое из которых имеет size длина (чтобы я мог написать arr(samevaluearray(n,size))) или я пропустил удобный конструктор для MultiArray?

Редактировать: Он должен работать независимо от определенного значения n, т.е. arr({{size,size}} будет работать только для n=2.

Поскольку это может быть непонятно: boost::multi_array<char,n>(boost::extents[4][4][4]) корректно инициализирует массив 4x4x4, но каждый раз n изменяется в исходном коде, каждая инициализация должна обновляться вручную, так что это не вариант.

Это было полезно?

Решение 2

Оказывается, std::vector имеет конструктор, который создает вектор с постоянным значением, повторяющимся n раз, поэтому возможное решение выглядит следующим образом:

const int n=2, size=4; //# of dimensions and size of one dimension
boost::multi_array<char,n> arr(std::vector<size_t>(n,size));

Это инициализирует n-мерный multi_array с размером каждого измерения, равным size.

Другие советы

Вы можете инкапсулировать создание массива во вспомогательную функцию:

template <typename T, size_t N>
boost::multi_array<T, N> make_regular_matrix(const size_t m)
{
    boost::multi_array<T, N> arr;
    boost::array<size_t, N> extents;
    extents.assign(m);
    arr.resize(extents);

    return arr;
}

const int n = 3;
int size = 4; // Can be const as well, but this is not mandatory

auto arr = make_regular_matrix<char, n>(size);

Если вы не можете использовать auto, вам придется продублировать параметры шаблона:

boost::multi_array<char, n> arr = make_regular_matrix<char, n>(size);

Тот Самый make_regular_matrix функция может быть сокращена до использования std::vector, как вы сделали в своем ответе;Я не знаю, была бы ли эта реализация лучше.Цель вспомогательной функции - скрыть создание массива, но могут быть написаны и другие версии, например, для инициализации элементов массива заданным значением:

template <size_t N, typename T> //switched order for deduction
boost::multi_array<T, N> make_regular_matrix(const size_t m, const T & value)
{
     boost::multi_array<T, N> arr(std::vector<size_t>(n, m));

     std::fill(arr.data(), arr.data() + arr.num_elements(), value);

     return arr;
}

auto arr = make_regular_matrix<4>(3, 'z'); //creates a 3x3x3x3 matrix
                                           //filled with 'z's

Из самого Расширьте документацию по нескольким массивам, да, вы можете инициализировать его одной строкой:

typedef boost::multi_array<double, 3> array_type;
typedef array_type::index index;
array_type A(boost::extents[3][4][2]);

Определения типов предназначены для удобства чтения, с таким же успехом это можно сделать и для вашего примера:

boost::multi_array<int, 2> arr(boost::extents[2][4]);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top