C++ 运算符[][] 重载
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6969881/
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
Operator[][] overload
提问by icepopo
Is it possible to overload []
operator twice? To allow, something like this: function[3][3]
(like in a two dimensional array).
是否可以重载[]
运算符两次?允许,像这样:(function[3][3]
就像在二维数组中一样)。
If it is possible, I would like to see some example code.
如果可能的话,我想看看一些示例代码。
回答by Seth Carnegie
You can overload operator[]
to return an object on which you can use operator[]
again to get a result.
您可以重载operator[]
以返回一个对象,您可以operator[]
再次使用该对象来获取结果。
class ArrayOfArrays {
public:
ArrayOfArrays() {
_arrayofarrays = new int*[10];
for(int i = 0; i < 10; ++i)
_arrayofarrays[i] = new int[10];
}
class Proxy {
public:
Proxy(int* _array) : _array(_array) { }
int operator[](int index) {
return _array[index];
}
private:
int* _array;
};
Proxy operator[](int index) {
return Proxy(_arrayofarrays[index]);
}
private:
int** _arrayofarrays;
};
Then you can use it like:
然后你可以像这样使用它:
ArrayOfArrays aoa;
aoa[3][5];
This is just a simple example, you'd want to add a bunch of bounds checking and stuff, but you get the idea.
这只是一个简单的例子,你想添加一堆边界检查和东西,但你明白了。
回答by Lightness Races in Orbit
An expression x[y][z]
requires that x[y]
evaluates to an object d
that supports d[z]
.
表达式x[y][z]
要求x[y]
计算结果为d
支持d[z]
.
This means that x[y]
should be an object with an operator[]
that evaluates to a "proxy object" that alsosupports an operator[]
.
这意味着x[y]
应该是一个具有 的对象,该对象的operator[]
计算结果为也支持operator[]
.
This is the only way to chain them.
这是链接它们的唯一方法。
Alternatively, overload operator()
to take multiple arguments, such that you might invoke myObject(x,y)
.
或者,重载operator()
以接受多个参数,这样您就可以调用myObject(x,y)
.
回答by Bo Persson
For a two dimensional array, specifically, you might get away with a single operator[] overload that returns a pointer to the first element of each row.
具体而言,对于二维数组,您可能会避免使用单个 operator[] 重载,该重载返回指向每行第一个元素的指针。
Then you can use the built-in indexing operator to access each element within the row.
然后您可以使用内置索引运算符来访问行中的每个元素。
回答by John
It is possible if you return some kind of proxy class in first [] call. However, there is other option: you can overload operator() that can accept any number of arguments (function(3,3)
).
如果您在第一个 [] 调用中返回某种代理类,则有可能。但是,还有其他选择:您可以重载可以接受任意数量参数 ( function(3,3)
) 的operator( )。
回答by Ajay
One approach is using std::pair<int,int>
:
一种方法是使用std::pair<int,int>
:
class Array2D
{
int** m_p2dArray;
public:
int operator[](const std::pair<int,int>& Index)
{
return m_p2dArray[Index.first][Index.second];
}
};
int main()
{
Array2D theArray;
pair<int, int> theIndex(2,3);
int nValue;
nValue = theArray[theIndex];
}
Of course, you may typedef
the pair<int,int>
当然,您可以typedef
将pair<int,int>
回答by Node
You can use a proxy object, something like this:
您可以使用代理对象,如下所示:
#include <iostream>
struct Object
{
struct Proxy
{
Object *mObj;
int mI;
Proxy(Object *obj, int i)
: mObj(obj), mI(i)
{
}
int operator[](int j)
{
return mI * j;
}
};
Proxy operator[](int i)
{
return Proxy(this, i);
}
};
int main()
{
Object o;
std::cout << o[2][3] << std::endl;
}
回答by neuront
It 'll be great if you can let me know what function
, function[x]
and function[x][y]
are. But anyway let me consider it as an object declared somewhere like
这会是巨大的,如果你可以让我知道什么function
,function[x]
和function[x][y]
是。但无论如何让我将其视为在某处声明的对象
SomeClass function;
(Because you said that it's operator overload, I think you won't be interested at array like SomeClass function[16][32];
)
(因为你说它是运算符重载,我想你不会对像这样的数组感兴趣SomeClass function[16][32];
)
So function
is an instance of type SomeClass
. Then look up declaration of SomeClass
for the return type of operator[]
overload, just like
function
type 的实例也是如此SomeClass
。然后查找重载SomeClass
返回类型的 声明operator[]
,就像
ReturnType operator[](ParamType);
ReturnType operator[](ParamType);
Then function[x]
will have the type ReturnType
. Again look up ReturnType
for the operator[]
overload. If there is such a method, you could then use the expression function[x][y]
.
然后function[x]
会有类型ReturnType
。再次抬头ReturnType
的operator[]
过载。如果有这样的方法,那么您可以使用表达式function[x][y]
。
Note, unlike function(x, y)
, function[x][y]
are 2 separate calls. So it's hard for compiler or runtime garantees the atomicity unless you use a lock in the context. A similar example is, libc says printf
is atomic while successively calls to the overloaded operator<<
in output stream are not. A statement like
请注意,与 不同的是function(x, y)
,function[x][y]
是 2 个单独的调用。因此,除非您在上下文中使用锁,否则编译器或运行时很难保证原子性。一个类似的例子是,libc 说printf
是原子的,而连续调用operator<<
输出流中的重载则不是。像这样的声明
std::cout << "hello" << std::endl;
might have problem in multi-thread application, but something like
在多线程应用程序中可能有问题,但类似
printf("%s%s", "hello", "\n");
is fine.
很好。
回答by Kaustav Ray
#include<iostream>
using namespace std;
class Array
{
private: int *p;
public:
int length;
Array(int size = 0): length(size)
{
p=new int(length);
}
int& operator [](const int k)
{
return p[k];
}
};
class Matrix
{
private: Array *p;
public:
int r,c;
Matrix(int i=0, int j=0):r(i), c(j)
{
p= new Array[r];
}
Array& operator [](const int& i)
{
return p[i];
}
};
/*Driver program*/
int main()
{
Matrix M1(3,3); /*for checking purpose*/
M1[2][2]=5;
}
回答by Grandstack
struct test
{
using array_reference = int(&)[32][32];
array_reference operator [] (std::size_t index)
{
return m_data[index];
}
private:
int m_data[32][32][32];
};
Found my own simple solution to this.
找到了我自己的简单解决方案。
回答by Yakk - Adam Nevraumont
template<class F>
struct indexer_t{
F f;
template<class I>
std::result_of_t<F const&(I)> operator[](I&&i)const{
return f(std::forward<I>(i))1;
}
};
template<class F>
indexer_t<std::decay_t<F>> as_indexer(F&& f){return {std::forward<F>(f)};}
This lets you take a lambda, and produce an indexer (with []
support).
这使您可以使用 lambda,并生成索引器(有[]
支持)。
Suppose you have an operator()
that supports passing both coordinates at onxe as two arguments. Now writing [][]
support is just:
假设您有一个operator()
支持将 onxe 处的两个坐标作为两个参数传递。现在写作[][]
支持只是:
auto operator[](size_t i){
return as_indexer(
[i,this](size_t j)->decltype(auto)
{return (*this)(i,j);}
);
}
auto operator[](size_t i)const{
return as_indexer(
[i,this](size_t j)->decltype(auto)
{return (*this)(i,j);}
);
}
And done. No custom class required.
并做了。不需要自定义类。