C++ 在c++;类的成员是多维数组,其维度和范围在运行时之前是未知的?
我最初问过这个问题,但这并不意味着要用std::array来完成它C++ 在c++;类的成员是多维数组,其维度和范围在运行时之前是未知的?,c++,c++11,multidimensional-array,C++,C++11,Multidimensional Array,我最初问过这个问题,但这并不意味着要用std::array来完成它 这些问题及其答案提供了一些有用的信息,说明了如何使用Boost::MultiArray来避免在运行时需要知道维度的范围,但没有说明如何使用类成员来存储在运行时才知道维度和范围的数组(在运行时创建)。是。使用单个指针成员 多维数组实际上是一个指针。因此,您可以使用强制转换来计算动态n数组,并将该数组放入成员指针中 在你们班上应该是这样的 int * holder; void setHolder(int* anyArray){
这些问题及其答案提供了一些有用的信息,说明了如何使用Boost::MultiArray来避免在运行时需要知道维度的范围,但没有说明如何使用类成员来存储在运行时才知道维度和范围的数组(在运行时创建)。是。使用单个指针成员 多维数组实际上是一个指针。因此,您可以使用强制转换来计算动态n数组,并将该数组放入成员指针中 在你们班上应该是这样的
int * holder;
void setHolder(int* anyArray){
holder = anyArray;
}
使用:
只需避免多维数组:
template<typename T>
class Matrix
{
public:
Matrix(unsigned m, unsigned n)
: n(n), data(m * n)
{}
T& operator ()(unsigned i, unsigned j) {
return data[ i * n + j ];
}
private:
unsigned n;
std::vector<T> data;
};
int main()
{
Matrix<int> m(3, 5);
m(0, 0) = 0;
// ...
return 0;
}
获取任意维度和范围将遵循该方案并添加重载(以及维度/范围信息)和/或利用可变模板
有很多维度可以避免(即使在C++11中),并用std::vector替换参数。例如:T运算符(标准::向量索引)。
每个维度(除最后一个维度外)都将有一个扩展存储在向量n中(作为上面2D示例中的第一个维度)。根据您的偏好,您至少可以通过两种方式解决问题。首先,你不需要Boost库,你可以自己做
class array{
unsigned int dimNumber;
vector<unsigned int> dimSizes;
float *array;
array(const unsigned int dimNumber, ...){
va_list arguments;
va_start(arguments,dimNumber);
this->dimNumber = dimNumber;
unsigned int totalSize = 1;
for(unsigned int i=0;i<dimNumber;i++)
{
dimSizes.push_back(va_arg(arguments,double));
totalSize *= dimSizes[dimSizes.size()-1];
}
va_end(arguments);
array = new float[totalSize];
};
float getElement(unsigned int dimNumber, ...){
va_list arguments;
va_start(arguments,dimNumber);
unsgned int elementPos = 0, dimAdd = 1;
for(unsigned int i=0;i<dimNumber;i++)
{
unsigned int val = va_arg(arguments,double);
elementPos += dimAdd * val;
dimAdd *= dimsizes[i];
}
return array[elementPos]
};
};
类数组{
无符号整数;
矢量尺寸;
浮点*数组;
数组(常量无符号整数dimNumber,…){
va_列表参数;
va_开始(参数、dimNumber);
此->dimNumber=dimNumber;
无符号整数totalSize=1;
对于(unsigned int i=0;i您可以使用具有相同索引量的1D数组,而不是多维数组。我无法测试此代码,但我希望它能起作用,或者让您了解如何解决问题。您应该记住,数组从编译时起就没有固定长度,应该通过malloc()
或您的代码可能无法在其他计算机上运行。
(也许您应该为下面的代码创建一个类数组)
你的意思是编译时维度的数量未知,还是有N个未知大小的维度?据我所知(快速查看boost文档)您可以简单地指定构造函数中的所有内容,就像我所期望的那样。如果您在第一次尝试时查看我的解决方案:然后为构造函数保留一个维度向量和变量args,您应该知道如何做this@ZacHowland我的意思是维度的数量以及它们的范围(大小)在运行时是未知的。Glenn的答案将解决您的问题(坦率地说,这是唯一想要解决的问题),但听起来你仍然在遭受XY问题的困扰。为什么你认为你需要一个动态的维度数?不,只是不。这就是我要说的。好的,请解释一下。我们都只是在学习……我很高兴学习一些新的东西……这与void*multy=(void*)new vector[25];yourClass.setHolder((int*)multy)是一样的
而且可能不太安全类型转换必须根据维度数量及其范围进行动态转换。我不确定这是否可行,但我真的不认为这是可取的;我的直觉告诉我,这样的解决方案将涉及大量丑陋的c风格指针和内存管理ts和second试图避免使用C样式数组和。问题没有标记为C++11,因此我猜作者没有访问可变模板的权限,为每个dim添加重载是一个非常糟糕的主意……如果数据是50D(假设可能发生这种情况),该怎么办?@PawełStawarz我的错。我将添加c++11标记,因为这正是我正在使用的,如果可能的话,我更喜欢使用花哨的c++11语法/方法。而不是使用(I*m+j)*n+k
。通过这种方式,如果添加维度,就更容易递归地执行。此外,它还节省了乘法(顺便说一句,编译器可能已经注意到了这一点)-1适用于DIY和NIHS。一般来说,请在将代码作为权威答案发布之前对其进行测试。特别是,如果您认为自己可以做得比Boost更好,那么举证责任就在您身上。
T& operator ()(unsigned i, unsigned j, unsigned k) {
// Please optimize this (See @Alexandre C)
return data[ i*m*n + j*n + k ];
}
class array{
unsigned int dimNumber;
vector<unsigned int> dimSizes;
float *array;
array(const unsigned int dimNumber, ...){
va_list arguments;
va_start(arguments,dimNumber);
this->dimNumber = dimNumber;
unsigned int totalSize = 1;
for(unsigned int i=0;i<dimNumber;i++)
{
dimSizes.push_back(va_arg(arguments,double));
totalSize *= dimSizes[dimSizes.size()-1];
}
va_end(arguments);
array = new float[totalSize];
};
float getElement(unsigned int dimNumber, ...){
va_list arguments;
va_start(arguments,dimNumber);
unsgned int elementPos = 0, dimAdd = 1;
for(unsigned int i=0;i<dimNumber;i++)
{
unsigned int val = va_arg(arguments,double);
elementPos += dimAdd * val;
dimAdd *= dimsizes[i];
}
return array[elementPos]
};
};
#include <malloc.h>
int* IndexOffset; //Array which contains how many indices need to be skipped per dimension
int DimAmount; //Amount of dimensions
int SizeOfArray = 1; //Amount of indices of the array
void AllocateArray(int* output, //pointer to the array which will be allocated
int* dimLengths, //Amount of indices for each dimension: {1D, 2D, 3D,..., nD}
int dimCount){ //Length of the array above
DimAmount = dimCount;
int* IndexOffset = (int*) malloc(sizeof(int) * dimCount);
int temp = 1;
for(int i = 0; i < dimCount; i++){
temp = temp * dimLengths[i];
IndexOffset[i] = temp;
}
for(int i = 0; i < dimCount; i++){
SizeOfArray = SizeOfArray * dimLengths[i];
}
output = (int*)malloc(sizeof(int) * SizeOfArray);
}
int getArrayIndex(int* coordinates //Coordinates of the wished index as an array (like dimLengths)
){
int index;
int temp = coordinates[0];
for(int i = 1; i < DimAmount; i++){
temp = temp + IndexOffset[i-1] * coordinates[i];
}
index = temp;
return index;
}
for(int i = 0; i < SizeOfArray; i++){
free(output[i]);
}
free(output);