C++多维数组运算符

7

是否可以为多维数组某种程度上重载运算符?

例如:

class A {
  ...
  int& operator[][] (const int x, const int y);
  ...
}

这个回答解决了你的问题吗?Operator[][] overload - user10957435
8个回答

12

不行,那是不可能的。不过有两个替代方案:

你可以使operator[]返回一个较小维度的数组(对于3D数组,它将返回一个2D数组,对于2D数组,它将返回一个1D数组,而对于1D数组,它将返回单个元素)。然后你可以使用想要的语法来"串联"它们。(arr[x][y][z]

或者,你可以重载operator(),因为它可以接受多个参数。

然后你可以像这样使用它,例如索引到一个3D数组:arr(x,y,z)

但是你不能将[][][][][]作为单个运算符进行重载。


4

直接来说不行,但可以通过重载 operator[]() 并返回支持 operator[]() 的内容来实现相同的功能。

举个例子:

class A {
  std::vector<std::vector<int> > vec;
public:
  std::vector<int>& operator[] (int x)
  {
      return vec[x];
  }
};

这将允许您编写:

A a;
//...
int y = a[1][2];

因为 a[1] 返回一个你可以使用 operator[](2)std::vector<int>


在一般情况下,唯一的问题是没有保护措施来防止读取数组末尾的数据。因此,如果我的数组长度为4,并且我执行a[3][2]操作,那么第二个运算符就会溢出。 - iheanyi
@iheanyi 这实际上是预期的,即使对于 std::vector 也是如此。如果您想要保护,请使用 .at,它会抛出异常。 - Luchian Grigore
这就是为什么我说一般情况。如果我有自己的数组,想以这种方式访问它,而且我不能使用向量(或类似的东西 - 只是普通的数组),那么你的示例中没有内置的保护措施。 - iheanyi

2
不,只有 operator[]。作为替代方案,您可以重载它:
int &operator()(int x, int y);

您可以使用这个:
m(4, 5);

2
你需要重载 operator[] 并使其返回一个新的类,该类仅具有另一个 operator[]

2

自从C++23版本开始,重载的operator[]现在可以接受0个或多个参数,并且与operator()的行为完全相同。

class A {
  // ...
  int& operator[](std::size_t x, std::size_t j);
  // ...
};

调用:

A a = /* ... */;

a[1, 2]; // equivalent to 'a.operator[](1, 2)'

0

没有这样的运算符。我曾经实现过一个矩阵,试图接近STL标准。我使用了这种方法:首先我重载了operator[]以返回另一个类,我称之为_C_row:

_C_row operator[](size_type index) { return _C_row(/*some parameters*/); } ///< This operator is overloaded to permit the use of double pointer notation.
_C_row operator[](size_type index) const { return _C_row(/*some parameters*/); } ///< This operator is overloaded to permit the use of double pointer notation.

而在 _C_row 中,我重载了不止 operator[] 这个运算符:

value_type operator*() { return _r[0]; }
pointer operator->() { return _i[_idx]; }
double_pointer operator&() { return &(_i[_idx]); }
reference operator[](size_type col) { return _r[col]; }
const_reference operator[](size_type col) const { return _r[col]; }

我发现这个解决方案非常灵活。我希望我的答案对你有用。


0
如前所述,不存在operator[][]这样的运算符。但是,这里有一个使用嵌套类实现的方法,类似于“jalf”提出的方法。为了简单起见,我硬编码了一个3x3的原始数组。
    class Array2D final{
    public:
        class PartialArr final{
    private:
        friend Array2D;
        PartialArr(Array2D* ptr, int index) :original(ptr), firstIndex(index) {}
        int firstIndex;
        Array2D* original;
    public:
        int& operator[](int index) { return this->original->data[firstIndex][index];  }
    };

        PartialArr operator[](int index) { return PartialArr(this, index); }
    private:
        int data[3][3];
    };

这种解决方案可以防止在仅对数组的第一个维度进行索引时,Array2D 的用户直接操作数据。

也可以添加两个 operator[] 的 const 版本,使类更加完整。


0

这是一个单一的运算符被使用两次进行解引用。您可以通过将返回类型更改为[][],使用[]运算符进行解引用并执行功能和用法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接