带有多个参数的 C++ [] 数组运算符?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1936399/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ [] array operator with multiple arguments?
提问by genesys
Can I define in C++ an array operator that takes multiple arguments? I tried it like this:
我可以在 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];
}
But I'm getting this error:
但我收到此错误:
error C2804 binary operator '[' has too many parameters
采纳答案by jamesdlin
Nope, you can't overload operator[]
to accept multiple arguments. You instead can overload operator()
. See How do I create a subscript operator for a Matrix class?from the C++ FAQ.
不,您不能重载operator[]
以接受多个参数。相反,您可以重载operator()
. 请参阅如何为 Matrix 类创建下标运算符?来自 C++ 常见问题解答。
回答by Pavel Radzivilovsky
It is not possible to overload the []
operator to accept multiple arguments, but an alternative is to use the proxy pattern.
不可能重载[]
运算符以接受多个参数,但另一种方法是使用代理模式。
In two words: a[x][y]
, the first expression (a[x]
) would return a different type, named proxy type, which would have another operator[]
. It would call something like _storedReferenceToOriginalObject->At(x,y)
of the original class.
用两个词来说:a[x][y]
,第一个表达式 ( a[x]
) 将返回一个不同的类型,名为代理类型,它会有另一个operator[]
. 它会调用类似于_storedReferenceToOriginalObject->At(x,y)
原始类的东西。
You will not be able to do a[x,y]
, but I guess you wanted to overload the usual C++-style 2D array syntax anyway.
您将无法做到a[x,y]
,但我想您无论如何都想重载通常的 C++ 风格的 2D 数组语法。
回答by Ji?í Pospí?il
There's a nice little trick you can do with the uniform initialization syntax available in C++11. Instead of taking the index directly, you take a POD.
您可以使用 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];
}
And then use the new syntax:
然后使用新语法:
my_array<int> arr;
// ...
arr[{1, 2, 3}] = 42;
回答by tePer
For completeness sake: There is a way to actually use the bracket operator with multiple arguments, if they are not basic data types, namely by overloading the comma operatorand not the bracket operator, see the following post about comma overloading:
为了完整起见:有一种方法可以实际使用带有多个参数的括号运算符,如果它们不是基本数据类型,即通过重载逗号运算符而不是括号运算符,请参阅以下有关逗号重载的帖子:
https://stackoverflow.com/a/18136340/5836981
https://stackoverflow.com/a/18136340/5836981
Disclaimer:in my opinion overloading the comma operator is error prone and renders code more obscure, and is worth considering only in more exotic cases. I added this answer because I came over an instance of this in some code and it took me a while to figure out that the key was not the [] operator (which cannot be overloaded with multiple arguments) but the ,operator.
免责声明:在我看来,重载逗号运算符很容易出错并且会使代码更加晦涩难懂,并且仅在更奇特的情况下才值得考虑。我添加了这个答案,因为我在一些代码中遇到了这个实例,我花了一段时间才弄清楚关键不是 [] 运算符(它不能用多个参数重载)而是 , 运算符。
回答by gospes
N-dimensional arrays of arbitrary type and size in C++:
C++ 中任意类型和大小的 N 维数组:
This answer is inspired by the answer of Pavel Radzivilovsky, thanks for that. I had a bit of a hard time realizing the implementation, as it was my first stab at recursive templates. I'd like to share what I have done such that others can understand more quickly than I did.
这个答案的灵感来自 Pavel Radzivilovsky 的答案,谢谢。我很难实现实现,因为这是我第一次尝试递归模板。我想分享我所做的事情,以便其他人可以比我更快地理解。
I have written a c++ template class to create a n-dimensional array of arbitrary type and size. It needs to be instantiated with the array type and the number of dimensions. The size can be changed dynamically. I've given below a bare (stripped) working version of how to create a multidimensional array of which the elements can be accessed through successive application of the operator[](e.g. array[x][y][z]). This version can only handle arrays of dimension n>1. The main function shows how to create a 4-dimensional array of integers as an example.
我编写了一个 C++ 模板类来创建一个任意类型和大小的 n 维数组。它需要使用数组类型和维数进行实例化。大小可以动态更改。我在下面给出了如何创建一个多维数组的裸(剥离)工作版本,其中的元素可以通过operator[] 的连续应用访问(例如 array[x][y][z])。此版本只能处理维度 n>1 的数组。main 函数以创建 4 维整数数组为例。
EDIT: keep in mind that the example below is minimalfor readability, in that it does not deallocate the array, nor does it do bounds checking on access. Adding this is trivial, and left to the programmer.
编辑:请记住,下面的示例对于可读性而言是最小的,因为它不会释放数组,也不会对访问进行边界检查。添加它是微不足道的,留给程序员。
#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;
}
Enjoy.
享受。
回答by Moia
Edit: as pointed in comment, in C++20operator comma will be deprecated, so as the answer below.
编辑:正如评论中所指出的,在C++20运算符中,逗号将被弃用,因此下面的答案。
You can't overload operator[]
, but you can fake itby overloading operator,
instead.
你不能重载operator[]
,但你可以通过重载operator,
来伪造它。
Following your code it becomes:
按照你的代码它变成:
T& operator,(const int i, const int j, const int k){
return m_cells[k*m_resSqr+j*m_res+i];
}
now you'll be able to call
现在你可以打电话了
something[1, 2, 3]
You can extend it using templates, templates with variadic arguments, std::pair
or std::tuple
depending on your use case and C++ version
您可以使用模板、带有可变参数的模板std::pair
或std::tuple
根据您的用例和 C++ 版本扩展它