C ++:可变长度多维数组

时间:2014-08-20 10:54:22

标签: c++ c++11 multidimensional-array

我需要一个二维数组,其中两个维度的长度在编译时都是已知的。我希望[][]访问。

有几个问题,建议boost::multi_arraystd::vector<std::vector<type>>,为x维度分配一个数组,为y维度分配X数组,依此类推。

问题是我不控制数据,它已作为单个连续数组(大小x*y)存在。我有一个指向它的指针和两个维度的大小,我或多或少地包装它以获得[][]访问。

我想避免创建一大堆对象(比如分配一个std::vector的数组并将它们全部指向正确的东西),并提升。

我考虑创建一个类来保存维度和指针,并重载[][],但这不起作用,因为[][]是两个运算符,第二个[]适用于不同的对象。

最终,我正在寻找相当于使用[][]作为某种access(int x, int y)函数的语法糖的东西。这可能吗?

3 个答案:

答案 0 :(得分:1)

你可以将它包装在一个类中并重载operator [],例如:

template <typename T>
class MultiArray
{
public:
    explicit MultiArray(T* arr, int sizex, int sizey) : data(arr), sizey(sizey) {}

    const T* operator [] (int x) const { return &data[x * sizey]; }
    T* operator [] (int x) { return &data[x * sizey]; }

private:
    T* data;
    int sizey;
};

Live example

答案 1 :(得分:0)

您需要有两个类DataTypeP和DataTypePP。在初始化DataTypePP时,您需要将内存块分配给不同的DataTypeP引用。

class DataTypeP {
    int *ptr;
public:
    int operator[](int y){ return ptr[y];}
};
class DataTypePP{
    DataTypeP  *bPtr;
public:
    DataTypeP  operator[](int x){ return bPtr[x];}
};

int main(){
    DataTypePP a;
    cout<<a[1][2];
    return 0;
}

答案 2 :(得分:0)

使用std::vector<std::vector<type*>>,您可以使用自定义输入运算符构建内部向量,该运算符迭代您的数据并返回指向每个数据的指针。

例如:

size_t w, h;
int* myData = retrieveData(&w, &h);

std::vector<std::vector<int*>> data;
data.reserve(w);

template<typename T>
struct myIterator : public std::iterator<std::input_iterator_tag, T*>
{
    myIterator(T* data) :
      _data(data)
    {}
    T* _data;

    bool operator==(const myIterator& rhs){return rhs.data == data;}
    bool operator!=(const myIterator& rhs){return rhs.data != data;}
    T* operator*(){return data;}
    T* operator->(){return data;}

    myIterator& operator++(){data = &data[1]; return *this; }
};

for (size_t i = 0; i < w; ++i)
{
    data.emplace_back(myIterator<int>(&myData[i * h]),
        myIterator<int>(&myData[(i + 1) * h]));
}

Live example

此解决方案的优势在于为您提供了一个真正的STL容器,因此您可以使用特殊的for循环,STL算法等。

for (const auto& i : data)
  for (const auto& j : i)
    std::cout << *j << std::endl;

std::cout << "or with index access: " << std::endl;

for (size_t i = 0; i < w; ++i)
  for (size_t j = 0; j < h; ++j)
    std::cout << *data[i][j] << std::endl;

但是,它确实会创建指针向量,因此如果你使用像这样的小数据结构,你可以直接复制数组中的内容。