我需要一个二维数组,其中两个维度的长度在编译时都是已知的。我希望[][]
访问。
有几个问题,建议boost::multi_array
,std::vector<std::vector<type>>
,为x维度分配一个数组,为y维度分配X数组,依此类推。
问题是我不控制数据,它已作为单个连续数组(大小x*y
)存在。我有一个指向它的指针和两个维度的大小,我或多或少地包装它以获得[][]
访问。
我想避免创建一大堆对象(比如分配一个std::vector
的数组并将它们全部指向正确的东西),并提升。
我考虑创建一个类来保存维度和指针,并重载[][]
,但这不起作用,因为[][]
是两个运算符,第二个[]
适用于不同的对象。
最终,我正在寻找相当于使用[][]
作为某种access(int x, int y)
函数的语法糖的东西。这可能吗?
答案 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;
};
答案 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]));
}
此解决方案的优势在于为您提供了一个真正的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;
但是,它确实会创建指针向量,因此如果你使用像这样的小数据结构,你可以直接复制数组中的内容。