如何通过重载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 字节数组,除非 MN 是编译时常量(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))]