使用嵌套的std :: array创建一个多维数组,直到运行时才知道维度或范围

时间:2013-11-26 02:22:09

标签: c++ templates multidimensional-array template-meta-programming

一个类是否有可能拥有一个多维数组的成员,该数组的维度和范围在运行时才知道?

我发现(通过this guide)一种方法来创建一个结构,以便在编译时使用模板元编程轻松地嵌套std :: arrays:

#include <array>
/*
this struct allows for the creation of an n-dimensional array type
*/
template <typename T,size_t CurrentDimExtent,size_t... NextDimExtent>
struct MultiDimArray{
public:
//define the type name nestedType to be a recursive template definition.
  using nestedType=typename MultiDimArray<T,NextDimExtent...>::type;
  using type=std::array<nestedType,CurrentDimExtent>;
};
/*
This struct is the template specialization which handles the base case of the
 final dimensional extent
*/
template <typename T,size_t DimExtent>
struct MultiDimArray<T,DimExtent>{
  using type=std::array<T,DimExtent>;
};

这仍然无法以两种方式满足我的要求(我知道):

  1. 为了声明此类型的变量(或指向变量的指针),您必须说明尺寸。
  2. 仅当DimExtents是常量表达式(在编译时设置)时才有效。
  3. 为了说明为什么数字2是一个明显的问题,这里是一个具有设定维数(2)的类,使用void *来引用多维数组:

    template <typename T>
    class TwoDimGrid{
    public:
    TwoDimGrid(const size_t extent1,const size_t extent2):
     _twoDimArray(new MultiDimArray<T,extent1,extent2>);
    private:
    void* _twoDimArray;
    };
    

    这不会编译,因为extent1和extent2不是常量表达式。

    其他说明:

    • 我想看看是否可以使用std:array,而不是本机数组或动态调整大小的容器,如std :: vector。
    • 请在适当的地方使用智能指针(我没有,因为我不确定如何处理智能无效指针)。

    修改

    我陷入了The XY Problem的陷阱,X是这个问题的第一句话,Y是如何使用std :: array完成它。因此,我创建了一个new question,并将此文件留在这里以防万一有可能解决Y问题。

2 个答案:

答案 0 :(得分:0)

旧学校的多维数组,有以下几点:

template <typename T>
class multi
{
   T*myArray;
   size_t x_dim;
   size_t y_dim;
public:
   multi(size_t x, size t y) : x_dim(x), y_dim(y)
   {
        myArray = new T[x*y];
   }

   T& get(int x, int y)
   {
       return myArray[x*y_dim+y];
   }
};

答案 1 :(得分:0)

template <typename T>
class vvc
{
    //possible ragged array ..non rigorous approach
    //with management memory cost per element
    //clearly not as efficient as .... linearized access where access index is
    //row size * r + column
    //memory management courtesy of vector
    public:
    std::vector< std::vector<T> > v;
};

int double_vector()
{
    int x1 = 5;
    int x2 = 3;
    std::vector<int> r(x2);
    vvc<int> vv;
    int k = 0;
    for (int i1 = 0; i1 < x1; ++i1)
    {
        for (int i2 = 0; i2 < x2; ++i2)
        {
            k += 1;
            r[i2] = k;
        }
        vv.v.push_back(r);

    }
    //inspect
    cout << vv.v[0][0] << " first " << endl;
    for (auto const & t1 : vv.v)
    {
        for (auto const &t2 : t1 )
        {
            cout << t2 << " ";
        }
        cout << endl;
    }
    return 0;
}