Single line initializer for Boost.MultiArray

I have an n-dimensional Boost.MultiArray I am initialized as follows:

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); 

So, I have 4 lines of code to get a MultiArray, but I would like to do it on one line. Is there an easy way to generate a MultiArray with n dimensions, each of which has a length of size (so I can write arr(samevaluearray(n,size)) ), or did I skip the convenient constructor for MultiArray?

Edit: It should work regardless of the specific value of n, i.e. arr({{size,size}} will only work for n=2 .

Since this may not be clear: boost::multi_array<char,n>(boost::extents[4][4][4]) correctly initializes the 4x4x4 array, but every time n changes in the source code, each initialization must updated manually, so this is not an option.

+7
source share
3 answers

Turns off, std::vector has a constructor that constructs a vector with a constant value repeated n times, so a possible solution is as follows:

 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)); 

This initializes an n-dimensional multi_array with each size size set to size.

+5
source

You can encapsulate the creation of an array in a helper function:

 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); 

If you cannot use auto , you will have to duplicate the template parameters:

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

The make_regular_matrix function can be shortened to use std::vector , as in your answer; I do not know if this implementation will be better. The purpose of the helper function is to hide the creation of an array, but other versions can be written, for example, to initialize array elements with a given value:

 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 
+8
source

From the Boost Multi-Array documentation yes, you can initialize it in one line:

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

typedefs for readability can be just as easily done for your example:

 boost::multi_array<int, 2> arr(boost::extents[2][4]); 
+3
source

All Articles