如何链接多个运算符[]
How to chain multiple operator[]
我正在尝试创建一个使用运算符 [] 的 class,例如
MyClass[x][y]
并且它应该 return 一个基于我在 class 中定义的函数中调用的值。我目前拥有的是:
MyClass.h
class MyClass{
public:
// return one value of the matrix
friend double operator[][] (const int x, const int y);
}
我什至不认为我的语法是正确的,我如何在 MyClass.cpp 中编写这个函数来定义它应该的值 return?
喜欢是吗:
MyClass::friend double operator[][] (const int x, const int y)
{
// insert code here
}
试过了,一直报错。我相信那里一团糟...
非常感谢,
没有operator[][]
。但是您可以改为声明 operator()(int, int)
。
class Foo {
public:
double operator()(int a, int b) {
//...
}
};
如果您尝试创建 4x4 矩阵 class,我的方法和它在 D3DX 库中的方法是在 class 中有一个成员变量:
class Matrix
{
public:
// publicly accessible member 4x4 array
float m[4][4];
// also accessible via () operator. E.G. float value = mtx(3,2);
float operator()(int column, int row);
}
您需要return 该行的代理对象。这是一个非常简单的例子,只是为了让你继续。我没试过编译它。
class Matrix {
int data[4][4];
class Row {
Matrix* matrix;
int row;
int operator[](int index){
return matrix->data[row][index]; // Probably you want to check the index is in range here.
}
}
Row operator[](int row){
Row which_row;
which_row.matrix = this;
which_row.row = row; // beware that if the user passes the row around it might point to invalid memory if Matrix is deleted.
return which_row;
}
}
您也可以只 return 直接来自 operator[]
的行,而将第二个 []
保留为直接数组访问。恕我直言,代理对象很好,因为它可以对索引进行一些检查,并且可能还有其他不错的成员函数。
重载 operator()
绝对是最干净的方法。
但是,请记住这是 C++,您可以根据自己的意愿改变语法 :)
特别是,如果您坚持要使用 myclass[][]
,您可以通过声明一个 "intermediate class" 来实现,这里有一个例子:
#include <iostream>
using std::cout;
using std::endl;
class MyClass {
public:
using IndexType = int;
using ReturnType = double;
// intermediate structure
struct YClass {
MyClass& myclass;
IndexType x;
YClass (MyClass& c, IndexType x_) : myclass(c), x(x_) {}
ReturnType operator[](IndexType y_) { return myclass.compute(x, y_); }
};
// return an intermediate structure on which you can use opearator[]
YClass operator[](IndexType x) { return {*this, x}; }
// actual computation, called by the last "intremediate" class
ReturnType compute(IndexType x, IndexType y) {
return x * y;
}
};
int main()
{
MyClass myclass;
cout << myclass[2][3] << endl; // same as: cout << myclass.compute(2, 3) << endl;
}
我正在尝试创建一个使用运算符 [] 的 class,例如
MyClass[x][y]
并且它应该 return 一个基于我在 class 中定义的函数中调用的值。我目前拥有的是:
MyClass.h
class MyClass{
public:
// return one value of the matrix
friend double operator[][] (const int x, const int y);
}
我什至不认为我的语法是正确的,我如何在 MyClass.cpp 中编写这个函数来定义它应该的值 return?
喜欢是吗:
MyClass::friend double operator[][] (const int x, const int y)
{
// insert code here
}
试过了,一直报错。我相信那里一团糟...
非常感谢,
没有operator[][]
。但是您可以改为声明 operator()(int, int)
。
class Foo {
public:
double operator()(int a, int b) {
//...
}
};
如果您尝试创建 4x4 矩阵 class,我的方法和它在 D3DX 库中的方法是在 class 中有一个成员变量:
class Matrix
{
public:
// publicly accessible member 4x4 array
float m[4][4];
// also accessible via () operator. E.G. float value = mtx(3,2);
float operator()(int column, int row);
}
您需要return 该行的代理对象。这是一个非常简单的例子,只是为了让你继续。我没试过编译它。
class Matrix {
int data[4][4];
class Row {
Matrix* matrix;
int row;
int operator[](int index){
return matrix->data[row][index]; // Probably you want to check the index is in range here.
}
}
Row operator[](int row){
Row which_row;
which_row.matrix = this;
which_row.row = row; // beware that if the user passes the row around it might point to invalid memory if Matrix is deleted.
return which_row;
}
}
您也可以只 return 直接来自 operator[]
的行,而将第二个 []
保留为直接数组访问。恕我直言,代理对象很好,因为它可以对索引进行一些检查,并且可能还有其他不错的成员函数。
重载 operator()
绝对是最干净的方法。
但是,请记住这是 C++,您可以根据自己的意愿改变语法 :)
特别是,如果您坚持要使用 myclass[][]
,您可以通过声明一个 "intermediate class" 来实现,这里有一个例子:
#include <iostream>
using std::cout;
using std::endl;
class MyClass {
public:
using IndexType = int;
using ReturnType = double;
// intermediate structure
struct YClass {
MyClass& myclass;
IndexType x;
YClass (MyClass& c, IndexType x_) : myclass(c), x(x_) {}
ReturnType operator[](IndexType y_) { return myclass.compute(x, y_); }
};
// return an intermediate structure on which you can use opearator[]
YClass operator[](IndexType x) { return {*this, x}; }
// actual computation, called by the last "intremediate" class
ReturnType compute(IndexType x, IndexType y) {
return x * y;
}
};
int main()
{
MyClass myclass;
cout << myclass[2][3] << endl; // same as: cout << myclass.compute(2, 3) << endl;
}