定义维度为动态参数的多维数组

问题描述

我想创建一个函数来定义外部多维数组,如下所示: '''

const int SIZE=5; // SIZE will be dynamical
 int n1=2,n2=3,n3=4,n4=5,n5=6;
 int n_loop(SIZE)={n1,n2,n3,n4,n5};
 void Mul_array(int n_loop(SIZE))
{
        //here will define a multi-array
        // I don't kNow how to do this part
        external mul_array[n_loop[0]]....[n_loop[SIZE]]

}

因此,我可以通过仅设置n_loop [SIZE]来定义多维数组,这对我来说很方便。

解决方法

您无法获得任意长度或尺寸的数组。所有这些都必须在编译时知道。

但是,您可以获得一个足够大的一维动态数组以容纳多维数组,并手动执行数学运算以计算从N维到1维的映射。

为方便阅读和错误检查,而非为了提高速度,编写了以下内容。

#include <vector>
#include <iostream>
#include <cstddef>
#include <stdexcept>

// stupid helper function to get the poroduct of all the values in a vector
size_t multiply(const std::vector<size_t> & dims)
{
    size_t product = 1;
    for (size_t dim:dims)
    {
        product *= dim;
    }
    return product;
}

// spun off into own function for easier reading
// computes the offset for one dimension based on previous dimensions
size_t compute_dimension(size_t offset,size_t dim,size_t loc)
{
    if (loc < dim)
    {
        offset *= dim; // push existing offset into correct place for higher
                       // dimension
        offset += loc; // add on where to look in this dimension
        return offset;
    }
    throw std::out_of_range("useful error message goes here");
}
// map a multi dimensional corrodinate into a single dimension
size_t compute_offset(const std::vector<size_t> & dims,const std::initializer_list<size_t> & loc)
{
    if (dims.size() != loc.size())
    {
        throw std::runtime_error("Dimension mis-match");
    }
    auto locit = loc.begin();
    auto dimit = dims.begin();
    size_t offset = 0;
    while (locit < loc.end()) // compute the 1D offset dimension by dimension
    {
        offset = compute_dimension(offset,*dimit++,*locit++);
    }
    return offset;
}

class sdm_1 // Super Dimensional Matrix rev 1
{
public:
    sdm_1(const std::initializer_list<size_t> & dims) :
        mDims(dims),// Store dimensions
        mData(multiply(mDims)) // allocate storage for all dimensions
    {

    }
    // takes dimensions as a brace enclosed initializer list
    double& operator()(const std::initializer_list<size_t> & loc)
    {
        return mData[compute_offset(mDims,loc)];
    }
    double operator()(const std::initializer_list<size_t> & loc) const
    {
        return mData[compute_offset(mDims,loc)];
    }

    // silly little helper to display the array so we can see what's going on
    friend std::ostream & operator<<(std::ostream & out,const sdm_1 & sdm)
    {
        for (const auto & val: sdm.mData)
        {
            out << val << ' ';
        }
        return out;
    }

private:
    std::vector<size_t> mDims;
    std::vector<double> mData;
};

int main()
{
    sdm_1 test{2,3,4}; // make a 3D array
    std:: cout << test << std::endl; // print it
    for (size_t one = 0; one < 2; one++)
    {
        for (size_t two = 0; two < 3; two++)
        {
            for (size_t three = 0; three < 4; three++)
            {
                test({one,two,three}) = 1; // set a value in the array
                std:: cout << test << std::endl;
                test({one,three}) = 0; // and clear it so we get a nice 
                                           // number marching across the grid
            }
        }
    }
}

请注意,很少需要数量未知的尺寸。将会有一些时髦的可变参数模板voodoo,它们将允许在编译时设置维数。几乎可以肯定,这将是一个更快的解决方案。