c++ 用于Boost的单线初始化程序,MultiArray

e7arh2l6  于 12个月前  发布在  其他
关注(0)|答案(4)|浏览(117)

我有一个n维的Boost.MultiArray,我初始化如下:

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维的MultiArray,每个维的长度为size(所以我可以写arr(samevaluearray(n,size))),或者我错过了一个方便的MultiArray构造函数?

**编辑:**它应该不依赖于n的某个值,即arr({{size,size}}只适用于n=2

因为它可能不清楚:boost::multi_array<char,n>(boost::extents[4][4][4])正确地编译了一个4x4x4数组,但是每次在源代码中更改n时,每次初始化都必须手动更新,所以这不是一个选项。

sd2nnvve

sd2nnvve1#

你可以将数组的创建封装到一个helper函数中:

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

n1bvdmb6

n1bvdmb62#

原来,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都设置为size。

4dbbbstv

4dbbbstv3#

Boost Multi-Array documentation,是的,你可以初始化它一行:

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

字符串
typedef是为了可读性,你可以很容易地为你的例子做:

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

ykejflvf

ykejflvf4#

我认为这里的问题实际上是如何简单地生成具有单个值的常量静态数组。

template<std::size_t N>
std::array<size_t, N> make_regular_extents(std::size_t m) {
    std::array<size_t, N> extents;  // can be boost::array
    extents.fill(m);                // can be .assign for boost::array
    return extents;
}

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

    boost::multi_array<char, n> arr(make_regular_extents<n>(size));
}

字符串
或者在一行中(根据要求):

boost::multi_array<char, n> arr2(
        std::apply([size](auto... e) {return std::array{(e, size)...};}, std::array<int, n>{})
    );


https://godbolt.org/z/Y4Gs5q54e

相关问题