如何通过重载C++中的函数调用运算符得到存储在一维数组中的二维数组?
How can I get a two-dimension array that stored in an one-dimension array through overload the function call operator in C++?
我正在空闲时间编写一个小型科学计算库。我发现有人说将二维数组存储在一维数组中速度更快,您可以通过重载 function-all 运算符来实现。但是不知道怎么处理。
现在我认为函数数组应该这样做:
#include<iostream>
int main(){
int M=10;
int N=10;
double x[M*N];
cout<<x(m,n)<<endl;//print the m*N+n element of x
return 0;
}
我该怎么办?或者任何地方说 it.I 在 Whosebug 中看不到它....
x[m*N+n] 对于二维条件很有用。但是如果我有四维的话,就是x[m*A+n*B+p*C+l*D],每次用的时候,我都会写一大段...
这是您要找的吗? class Matrix1D 具有一维向量,但模拟二维矩阵,并允许您使用 ()-运算符访问它。
您可以通过修改 operator(...) 和 set(...) 函数将其扩展到任意多的维度。
#include <iostream>
#include <vector>
class Matrix1D {
private:
std::vector<double> x;
int N;
public:
Matrix1D(int m, int n) {
this->x = std::vector<double>(m * n);
this->N = n;
}
double operator()(int m, int n) { return this->x[m * this->N + n]; }
void set(int m, int n, double v) { this->x[m * this->N + n] = v; }
};
int main() {
Matrix1D c1(5, 5);
c1.set(3, 2, 1);
std::cout << c1(3, 2) << "\n";
}
在 C++ 中,运算符必须是 class 成员。因此,为了提供函数调用重载,您首先需要为您的数组创建自定义 class。
class oneDimArray {
private:
unsigned int lines;
unsigned int columns;
// You can replace the number with the maxim size of array desired
// be it another number or integer constant.
double x[100]{0};
public:
// Overloading the class constructor to accept 2D Arrays
oneDimArray(double [][100] matrix) {
// Getting the number of lines and columns
lines = sizeof matrix / sizeof matrix[0];
columns = sizeof[0] matrix / sizeof(double);
// Setting the elements
for(unsigned i = 0; i < lines*columns; i++) {
x[i] = matrix[i / columns][i % columns];
}
}
// Finally overloading the function call operator
double operator() (unsigned int line, unsigned int column) {
return x[line * lines + column];
}
};
在此之后,您所要做的就是创建一个 class(您的实际数组)的对象并对其进行初始化:
oneDimArray myArray = oneDimArray( someMatrix );
// Using the overloaded operator to access elements
myArray(1, 2);
以下可以推广到任何类型的数组。此外,如果您为输入 ( >> ) 运算符提供重载,您将能够直接读取它。
好吧,我承认您想编写一个科学计算库,并且(低级)优化很重要。这是我不只是说的唯一原因:不要担心低级数组,只使用向量的向量 [of vectors...]
但是 VLA 数组不是 C++ 的东西。它是一个(已记录的)gcc 扩展,也被 Clang 支持,但其他编译器将无法正确编译 double x[M*N];
,并且只保留一个 0 字节数组,除非 M
和 N
是编译时常量(constexpr
).
即使对于科学图书馆来说,x[i][j]
比 x[i*M + j]
干净的开销也微不足道。除非你能通过分析证明它既是必需的又是有效的,否则不要那样做。
话虽如此,如果您必须处理动态大小的多维数组,惯用语 x(i,j)
会很有用。我曾经尝试使用标准 []
符号为它构建一个通用库,它导致 nightmare.
您将需要:
a class 以承载适当尺寸的动态大小数组(您可以使用基于尺寸编号的模板)
一个大小沿所有维度分配底层一维数组的构造函数 - 我建议使用向量,除非你想明确处理 [=47= 的极端情况] construction/assignment(5 的规则)
operator()(int i, int j, ...)
的实现,具有正确的维数,仅 returns(对于维度 K、L、M、N 和坐标 i、j、k、 l):
x[l + K * (k + L * (j + M * i))]
我正在空闲时间编写一个小型科学计算库。我发现有人说将二维数组存储在一维数组中速度更快,您可以通过重载 function-all 运算符来实现。但是不知道怎么处理。
现在我认为函数数组应该这样做:
#include<iostream>
int main(){
int M=10;
int N=10;
double x[M*N];
cout<<x(m,n)<<endl;//print the m*N+n element of x
return 0;
}
我该怎么办?或者任何地方说 it.I 在 Whosebug 中看不到它....
x[m*N+n] 对于二维条件很有用。但是如果我有四维的话,就是x[m*A+n*B+p*C+l*D],每次用的时候,我都会写一大段...
这是您要找的吗? class Matrix1D 具有一维向量,但模拟二维矩阵,并允许您使用 ()-运算符访问它。
您可以通过修改 operator(...) 和 set(...) 函数将其扩展到任意多的维度。
#include <iostream>
#include <vector>
class Matrix1D {
private:
std::vector<double> x;
int N;
public:
Matrix1D(int m, int n) {
this->x = std::vector<double>(m * n);
this->N = n;
}
double operator()(int m, int n) { return this->x[m * this->N + n]; }
void set(int m, int n, double v) { this->x[m * this->N + n] = v; }
};
int main() {
Matrix1D c1(5, 5);
c1.set(3, 2, 1);
std::cout << c1(3, 2) << "\n";
}
在 C++ 中,运算符必须是 class 成员。因此,为了提供函数调用重载,您首先需要为您的数组创建自定义 class。
class oneDimArray {
private:
unsigned int lines;
unsigned int columns;
// You can replace the number with the maxim size of array desired
// be it another number or integer constant.
double x[100]{0};
public:
// Overloading the class constructor to accept 2D Arrays
oneDimArray(double [][100] matrix) {
// Getting the number of lines and columns
lines = sizeof matrix / sizeof matrix[0];
columns = sizeof[0] matrix / sizeof(double);
// Setting the elements
for(unsigned i = 0; i < lines*columns; i++) {
x[i] = matrix[i / columns][i % columns];
}
}
// Finally overloading the function call operator
double operator() (unsigned int line, unsigned int column) {
return x[line * lines + column];
}
};
在此之后,您所要做的就是创建一个 class(您的实际数组)的对象并对其进行初始化:
oneDimArray myArray = oneDimArray( someMatrix );
// Using the overloaded operator to access elements
myArray(1, 2);
以下可以推广到任何类型的数组。此外,如果您为输入 ( >> ) 运算符提供重载,您将能够直接读取它。
好吧,我承认您想编写一个科学计算库,并且(低级)优化很重要。这是我不只是说的唯一原因:不要担心低级数组,只使用向量的向量 [of vectors...]
但是 VLA 数组不是 C++ 的东西。它是一个(已记录的)gcc 扩展,也被 Clang 支持,但其他编译器将无法正确编译 double x[M*N];
,并且只保留一个 0 字节数组,除非 M
和 N
是编译时常量(constexpr
).
即使对于科学图书馆来说,x[i][j]
比 x[i*M + j]
干净的开销也微不足道。除非你能通过分析证明它既是必需的又是有效的,否则不要那样做。
话虽如此,如果您必须处理动态大小的多维数组,惯用语 x(i,j)
会很有用。我曾经尝试使用标准 []
符号为它构建一个通用库,它导致 nightmare.
您将需要:
a class 以承载适当尺寸的动态大小数组(您可以使用基于尺寸编号的模板)
一个大小沿所有维度分配底层一维数组的构造函数 - 我建议使用向量,除非你想明确处理 [=47= 的极端情况] construction/assignment(5 的规则)
operator()(int i, int j, ...)
的实现,具有正确的维数,仅 returns(对于维度 K、L、M、N 和坐标 i、j、k、 l):x[l + K * (k + L * (j + M * i))]