C ++ []数组运算符有多个参数?

时间:2009-12-20 17:22:40

标签: c++ arrays operators operator-keyword

我可以在C ++中定义一个带有多个参数的数组运算符吗?我试过这样的话:

const T& operator[](const int i, const int j, const int k) const{ 
    return m_cells[k*m_resSqr+j*m_res+i];
}

T& operator[](const int i, const int j, const int k){ 
    return m_cells[k*m_resSqr+j*m_res+i];       
}

但是我收到了这个错误:

error C2804 binary operator '[' has too many parameters

6 个答案:

答案 0 :(得分:43)

不,你不能重载operator[]来接受多个参数。您可以重载operator()。请参阅C ++常见问题解答中的How do I create a subscript operator for a Matrix class?

答案 1 :(得分:40)

无法重载[]运算符以接受多个参数,但另一种方法是使用代理模式

用两个词:a[x][y],第一个表达式(a[x])将返回一个名为代理类型的不同类型,它将具有另一个operator[]。它会调用原始类的_storedReferenceToOriginalObject->At(x,y)之类的东西。

你将无法做a[x,y],但我想你想要重载通常的C ++风格的2D数组语法。

答案 2 :(得分:36)

使用C ++ 11中提供的统一初始化语法可以做一个很好的小技巧。不是直接获取索引,而是选择POD。

struct indices
{
  std::size_t i, j, k;
};

T& operator[](indices idx)
{
  return m_cells[idx.k * m_resSqr + idx.j * m_res + idx.i];
}

然后使用新语法:

my_array<int> arr;
// ...
arr[{1, 2, 3}] = 42;

答案 3 :(得分:10)

为了完整起见:有一种方法可以实际使用包含多个参数的括号运算符,如果它们不是基本数据类型, 即通过重载逗号运算符而不是括号运算符,请参阅以下有关逗号重载的帖子:

https://stackoverflow.com/a/18136340/5836981

免责声明:在我看来,重载逗号运算符很容易出错并且使代码更加模糊,仅在更奇特的情况下才值得考虑。我添加了这个答案,因为我在一些代码中遇到了这个实例,我花了一段时间才发现密钥不是[]运算符(不能用多个参数重载)而是运算符。

答案 4 :(得分:2)

C ++中任意类型和大小的N维数组:

这个答案的灵感来自Pavel Radzivilovsky的答案,谢谢你。我有点难以实现实现,因为这是我对递归模板的第一次尝试。我想分享我所做的事情,以便其他人比我更快地理解。

我编写了一个c ++模板类来创建任意类型和大小的n维数组。它需要使用数组类型和维度数进行实例化。大小可以动态更改。我在下面给出了一个如何创建多维数组的裸(剥离)工作版本,其中元素可以通过连续应用运算符[] 来访问(例如array [x] [ Y] [Z])。此版本只能处理维度n> 1的数组。 main函数显示了如何创建一个4维整数数组作为示例。

编辑:请记住,下面的示例是 minimal 以提高可读性,因为它不会释放数组,也不会对访问进行边界检查。添加它是微不足道的,留给程序员。

#include <stdio.h>
#include <stdlib.h>

template <typename T, int N>
struct array {
    array<T,N>() : data(NULL), offset((int*) malloc(sizeof(int)*N)){}
    array<T,N>(T *data, int *offset) : data(data), offset(offset){}
    array<T,N-1> operator[](int i){return array<T,N-1>(&data[i*offset[N]], offset);}
    bool resize(int *size){
        offset[N-1] = 1;
        int total_size = size[N-1];
        for(int i = N-2; i >= 0; i--){
            total_size *= size[i];
            offset[i] = offset[i+1]*size[i+1];
        }
        return (data = (T*) realloc (data, total_size*sizeof(T)));
    }
    T *data;
    int *offset;
};

template <typename T>
struct array<T,1>{
    array<T,1>(T *data, int *offset) : data(data){}
    T& operator[](int i){return data[i];}
    T *data;
};

int main () {
    array<int, 4> a;

    // create array with dimensions [1][3][3][7]
    int size[4] = { 1, 3, 3, 7 };
    a.resize(size);               

    a[0][1][2][3] = 123;

    return 0;
}

享受。

答案 5 :(得分:1)

编辑:如注释中所述,在 C ++ 20 中,运算符逗号将被弃用,如下所示。

您不能重载operator[],但是您可以通过重载operator,来伪造

在您的代码之后,它变为:

T& operator,(const int i, const int j, const int k){ 
    return m_cells[k*m_resSqr+j*m_res+i];       
}

现在您可以拨打电话

something[1, 2, 3]

您可以使用模板,带有可变参数的模板,std::pairstd::tuple来扩展它,具体取决于您的用例和C ++版本