c++ - C++ 中内置类型的运算符重载以访问二维数组中的元素

标签 c++ arrays multidimensional-array operator-overloading

我正在为二维数组指针寻找重载 [] 运算符 访问单元格元素。

二维数组作为 int *arr 传递到我的函数。

我们可以通过 *(arr+i*N+j) 访问单元格元素,其中 N 是列数 i 是行索引,j 是列索引。

但是我们可以这样写吗 arr[i,j]arr(i,j) 以获得更好的可读性 使用一些宏或运算符重载?

有什么建议吗?

最佳答案

你不能直接这样做。
我建议写一个小类/结构来方便地包装你的二维数组。这里我用std::vector而不是 int *arr而且您不必关心内存管理。以下代码提供了 3 种可能的方法:

方法一(推荐):通过mat(i,j)访问

operator()(size_t i, size_t j)称为函数调用运算符

template<typename T>
struct Matrix
{
    Matrix(const std::vector<T>& d, size_t s) : Matrix(d, s, s) {}
    Matrix(const std::vector<T>& d, size_t c, size_t r) : data_(d), cols_(c), rows_(r) {}
    std::vector<T> data_;
    size_t    cols_;
    size_t    rows_;
    const T& operator()(size_t i, size_t j) const { return data_[i * cols_ + j]; }
          T& operator()(size_t i, size_t j)       { return data_[i * cols_ + j]; }
    // and you can add other convenient methods
};

像这样使用它:

   Matrix<int> mat({1, 2, 3, 4, 5, 6, 7, 8, 9}, 3, 3); // a 3x3 matrix
   std::cout << mat(1,2) << std::endl;

Live code

如果您在编译时知道大小,那么您可以使用 std::array并相应地更改您的结构:

template<typename T, size_t Cols, size_t Rows> struct Matrix 
{ 
  std::array<T, Cols * Rows> data_; 
  // etc...

方法二:通过mat[{i,j}]访问

使用数组下标运算符只接受一个参数,因此您可以更改/添加以下运算符到您的类中:

const T& operator[](const std::array<size_t,2>& a) const { return data_[a[0] * cols_ + a[1]]; }
      T& operator[](const std::array<size_t,2>& a)       { return data_[a[0] * cols_ + a[1]]; }

可以这样调用:

std::cout << mat[{1,2}] << std::endl;

请注意,当您在多个维度上工作时,此方法很有用(您不必编写多个 operator()(size_t i, size_t j, size_t k, etc...)

方法三(不推荐):通过mat[Idx(i),Idx(j)]访问

您可以使用数组下标运算符获取两个参数,但您必须重载逗号运算符,这在两个内置类型之间是不可能的...所以直接访问通过mat[i,j]不可能(感谢 leemes 指出这一点的评论)。

但是您可以创建自己的类型并重载它。这里有一个例子(把它放在你的 Matrix 类定义之前):

struct Idx 
{
    Idx(size_t ii) : i(ii) {}
    size_t i;
    operator size_t() const { return i; } // implicit user-defined conversion
};

std::array<size_t, 2> operator , (Idx i1, Idx i2)
{
    return { i1, i2 };
}

// etc...
// and we do not have to add Matrix operators since we reused the one from Method 2

像这样使用它:

std::cout << mat[Idx(1),Idx(2)] << std::endl;

这不是那么优雅......

Complete and final live code

关于c++ - C++ 中内置类型的运算符重载以访问二维数组中的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33541144/

相关文章:

arrays - 如果条目不包含两个匹配的字段,mongo 添加到嵌套数组

javascript - 在javascript中操作多维数组

c - 指向多维数组的指针错误: Expression must have pointer-to-object type

c++ - 帮助我理解这个奇怪的 C++ 代码

c++ - 通过唯一 ID 连接到主机,而不是 IP?

c++ - 使用函数输出字符串或字符。小白

c - 我的二维数组中数字的频率无法正确输出

arrays - 在Go中调用WebAssembly代码时如何使用Go slice?

python - 如何沿批量维度广播 numpy 索引?

c++ - 编程难题的建议算法