我可以在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
答案 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::pair
或std::tuple
来扩展它,具体取决于您的用例和C ++版本