C++ C++;:可变长度多维数组
我需要一个二维数组,其中两个维度的长度在编译时都是未知的。我想要C++ C++;:可变长度多维数组,c++,c++11,multidimensional-array,C++,C++11,Multidimensional Array,我需要一个二维数组,其中两个维度的长度在编译时都是未知的。我想要[]]访问权限 关于这一点,已经有几个问题,建议boost::multi_array,std::vector,为x维分配一个数组,为y维分配x数组,等等 问题是我不控制数据,它已经作为单个连续数组存在(大小x*y)。我有一个指向它的指针和两个维度的大小,我或多或少地包装它以获得[]]访问权限 我希望避免创建一大堆对象(比如分配一个std::vectors数组,并将它们全部指向正确的对象)和boost 我考虑过创建一个同时包含维度和指
[]]
访问权限
关于这一点,已经有几个问题,建议boost::multi_array
,std::vector
,为x维分配一个数组,为y维分配x数组,等等
问题是我不控制数据,它已经作为单个连续数组存在(大小x*y
)。我有一个指向它的指针和两个维度的大小,我或多或少地包装它以获得[]]
访问权限
我希望避免创建一大堆对象(比如分配一个std::vector
s数组,并将它们全部指向正确的对象)和boost
我考虑过创建一个同时包含维度和指针的类,并重载[]
,但这不起作用,因为[]
是两个运算符,第二个[]
应用于不同的对象
最终,我要寻找的东西相当于使用
[][]
作为某种访问(intx,inty)
函数的语法糖。这可能吗?您需要有两个类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;
}
类数据类型p{
int*ptr;
公众:
int运算符[](int y){return ptr[y];}
};
类DataTypePP{
数据类型P*bPtr;
公众:
DataTypeP运算符[](int x){返回bPtr[x];}
};
int main(){
数据类型PP a;
cout您可以将其包装在类中并重载运算符[]
,类似于:
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;
};
模板
类多数组
{
公众:
显式多数组(T*arr,int-sizex,int-sizey):数据(arr),sizey(sizey){
常量T*运算符[](int x)常量{return&data[x*sizey];}
T*运算符[](int x){return&data[x*sizey];}
私人:
T*数据;
int SIZE;
};
使用std::vector
,您可以使用自定义输入操作符构建内部向量,该操作符迭代数据并返回指向每个数据的指针
例如:
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]));
}
尺寸w,h;
int*myData=retrieveData(&w,&h);
std::矢量数据;
数据。储量(w);
模板
struct myIterator:public std::iterator
{
myIterator(T*数据):
_数据(数据)
{}
T*_数据;
bool运算符==(const myIterator&rhs){return rhs.data==data;}
布尔运算符!=(常量myIterator&rhs){return rhs.data!=data;}
T*运算符*(){返回数据;}
T*运算符->(){返回数据;}
myIterator&operator++(){data=&data[1];返回*this;}
};
对于(尺寸i=0;i
此解决方案的优点是为您提供了一个真正的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;
for(const auto&i:data)
用于(康斯特汽车与j:i)
std::cout main[]返回一个代理对象,该对象指向原始对象并存储第一个维度,其[]接受第二个维度
而不是处理一个临时对象。@Rapptz的链接确实回答了这个问题,所以这肯定是重复的。| |重复回答一个重复的问题。@MatthiasB:重复的问题使用多个数组,而OP有一个唯一的1D数组。这是重复的问题,但不是重复的答案。prem.baranwal suggEST创建一个指针数组作为代理,而这意味着重载一个操作符[]
,并让编译器正常处理第二个[]
。实际上,go-to问题没有这个答案(一个人建议了,但不想尝试),所以我要接受这个,因为它实际上非常有用,因为我只处理二维问题。@Monchoman45那么这应该合并,或者作为改进/编辑添加到原始问题的答案中。@Jaroj42 OP特别要求双[]
运算符,独立于1d或2d数组。虽然实现略有不同,但最终的结构非常相似。因此,在我看来,它是重复的…这不是创建了Y+1std::vector
实例吗?它看起来也像是在复制整个原始表。不,它只是复制指向数据的指针,所以这里是我的nts它是无用的,但对于更复杂的数据,这可能是有趣的。它创建了包含H指针的std::vector的W个实例。我这里没有编译器来测试代码,但这应该可以工作,如果没有,我们可以修复它!