两个方括号重载

发布于 2024-10-31 19:30:19 字数 227 浏览 0 评论 0原文

我正在用 C++ 编写一个矩阵类,并尝试重载一些运算符,例如 = 和 >>和<<等等。

我无法重载矩阵类的运算符 [][] 。 如果我有一个像 M1 这样的类矩阵的对象,那么我可以使用这种方式为每个元素赋予值:

M1[1][2]=5;

或者

int X;

X=M1[4][5];

I am writing a matrix class in c++ and trying to overload some operator like = and >> and << etc.

I was unable to overload operator [][] for matrix class.
if i have an object of class matrix like M1 then i can use this way for giving value to each element:

M1[1][2]=5;

OR

int X;

X=M1[4][5];

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

神爱温柔 2024-11-07 19:30:19

只需重载operator[]并使其返回指向矩阵相应行或列的指针即可。由于指针支持 [] 下标,因此可以通过“双平方”表示法 [][] 进行访问。

您还可以使用两个参数重载operator()

Just overload operator[] and make it return a pointer to the respective row or column of the matrix. Since pointers support subscripting by [], access by the 'double-square' notation [][] is possible then.

You can also overload operator() with two arguments.

快乐很简单 2024-11-07 19:30:19

C++ 中没有operator[][]。您必须返回一个辅助对象,然后为其重载operator[],才能获得这种访问权限。

There is no operator[][] in C++. You have to return a helper object and then overload operator[] for that too, to have this kind of access.

著墨染雨君画夕 2024-11-07 19:30:19

您可以重载operator[]。因此,如果您想以这种方式使用矩阵,则应该将矩阵制作为向量数组。

class Matrix
{
...
  Vector & operator[]( int index );
...
};

最后

class Vector
{
...
  double & operator[]( int index );
...
};

Matrix m;
...
double value = m[i][j];
...

You could overload operator[]. So if you would like to use matrix that way, you should make matrix as array of vectors.

class Matrix
{
...
  Vector & operator[]( int index );
...
};

and

class Vector
{
...
  double & operator[]( int index );
...
};

Finally:

Matrix m;
...
double value = m[i][j];
...
不喜欢何必死缠烂打 2024-11-07 19:30:19

没有operator[][],可以实现operator[]来返回对行/列对象的引用,在该对象中可以实现operator [] 返回单元格引用。

您可以执行如下操作来避免所有麻烦。

struct loc
{
  int x;
  int y;
};

然后在您的operator[]重载中,接受loc,例如

T& operator[](loc const& cLoc)
{
 // now you have x/y you can return the object there.
}

要调用,您可以简单地执行某些操作喜欢:

matrix[loc(2,3)] = 5; 

there is no operator[][], you can implement operator[] to return a reference to the row/column object, in which you can implement the operator[] to return you the cell reference.

You can do something like the following to avoid all that hassle..

struct loc
{
  int x;
  int y;
};

then in your operator[] overload, accept a loc, something like

T& operator[](loc const& cLoc)
{
 // now you have x/y you can return the object there.
}

To call, you can simply do something like:

matrix[loc(2,3)] = 5; 
菊凝晚露 2024-11-07 19:30:19

事实上,几年前我在自己的矩阵课上就是这么做的。在本例中,我定义了一个矩阵模板类,其中包含下面的代码片段。

然后我能够迭代并分配如下:

          for(size_t k=1; k<n; ++k) {       
                   minor[p][k-1]=major[j][k];        
           }

我希望这会有所帮助。

// //////////////////////////////////////////////////////////////////////////////
// list is internal vector representation of n x m matrix
T* list;
// Proxy object used to provide the column operator
template < typename T >
class OperatorBracketHelper
{
    Matrix < T > & parent ;
    size_t firstIndex ;

    public :
        OperatorBracketHelper ( Matrix < T > & Parent , size_t FirstIndex ) : 
        parent ( Parent ), firstIndex ( FirstIndex ) {}

        // method called for column operator
        T & operator []( size_t SecondIndex )
        {
            // Call the parent GetElement method which will actually retrieve the element
            return parent.GetElement ( firstIndex , SecondIndex );
        }
};

// method called for row operator
OperatorBracketHelper < T > operator []( size_t FirstIndex )
{
    // Return a proxy object that "knows" to which container it has to ask the element
    // and which is the first index (specified in this call)
    return OperatorBracketHelper < T >(* this , FirstIndex );
}

T & GetElement ( size_t FirstIndex , size_t SecondIndex )
{
    return list[FirstIndex*cols+SecondIndex];
}

Actually, I did just that in my own matrix class a few years ago. In this case, I defined a matrix template class that contained the snippet, below.

I was then able to iterate and assign as follows:

          for(size_t k=1; k<n; ++k) {       
                   minor[p][k-1]=major[j][k];        
           }

I hope this helps.

// //////////////////////////////////////////////////////////////////////////////
// list is internal vector representation of n x m matrix
T* list;
// Proxy object used to provide the column operator
template < typename T >
class OperatorBracketHelper
{
    Matrix < T > & parent ;
    size_t firstIndex ;

    public :
        OperatorBracketHelper ( Matrix < T > & Parent , size_t FirstIndex ) : 
        parent ( Parent ), firstIndex ( FirstIndex ) {}

        // method called for column operator
        T & operator []( size_t SecondIndex )
        {
            // Call the parent GetElement method which will actually retrieve the element
            return parent.GetElement ( firstIndex , SecondIndex );
        }
};

// method called for row operator
OperatorBracketHelper < T > operator []( size_t FirstIndex )
{
    // Return a proxy object that "knows" to which container it has to ask the element
    // and which is the first index (specified in this call)
    return OperatorBracketHelper < T >(* this , FirstIndex );
}

T & GetElement ( size_t FirstIndex , size_t SecondIndex )
{
    return list[FirstIndex*cols+SecondIndex];
}
无名指的心愿 2024-11-07 19:30:19

我正在研究一个矩阵类,我决定首先创建一个具有动态二维数组的 Array 类。所以,就像你一样,我也面临着如何重载两个方括号的障碍。我处理这个案例的方法非常简单;我将方括号运算符作为成员函数重载了两次。首先,我重载了 [] 以便返回一个指向所需行的指针,可以这么说,然后下面的成员函数(即再次重载了运算符 [])返回与数组元素类型相同的左值。

但是,请注意,您用于调用前一个重载运算符 [] 的索引必须保存在某个位置,以便您可以在后一个重载运算符 [] 中使用它。出于这个原因,我只是向 Array 类添加了一个 int 类型的新成员(我在下面的代码中将其命名为“test”)。

class Array {

private: 

 double **ptr; int test;
 ...   /* the rest of the members includes the number of rows and columns */

public:
    Array(int=3,int=3);  // Constructor
    Array(Array &);      // Copy Constructor
    ~Array();            // Destructor
    void get_array();
    void show_array();
    double* operator[] (int);
    double operator[] (short int);
    ...
};

... 

double* Array::operator[] (int a) {
    test = a;
    double* p = ptr[test];
    return p;
}

double Array::operator[] (short int b) {
   return ((*this)[test][b]);
}

因此,作为一个例子,我可以在 main 中简单地写:

int main(){
Array example;
cout << example[1][2];  
}

我希望这对你有帮助。

I am exactly working on a matrix class and I decided to first create an Array class which has a dynamic 2-D array. So, well just as you, I confronted this obstacle that how I can overload two square brackets. How I approached this case is very simple; I overloaded the square brackets operator twice as member functions. First, I overloaded [] so as to return a pointer pointing to the desired row, so to speak, and then the following member function (i.e. again operator [] overloaded) returns a lvalue of the same type as the array's elements.

However, note that the index you inter to invoke the former overloaded operator [] must be saved somewhere so that you may use it in the latter overloaded operator []. For this reason I simply added a new member of the type int to the class Array (which I've named it "test" in my code below).

class Array {

private: 

 double **ptr; int test;
 ...   /* the rest of the members includes the number of rows and columns */

public:
    Array(int=3,int=3);  // Constructor
    Array(Array &);      // Copy Constructor
    ~Array();            // Destructor
    void get_array();
    void show_array();
    double* operator[] (int);
    double operator[] (short int);
    ...
};

... 

double* Array::operator[] (int a) {
    test = a;
    double* p = ptr[test];
    return p;
}

double Array::operator[] (short int b) {
   return ((*this)[test][b]);
}

Therefor, as an example, in main I can simply write:

int main(){
Array example;
cout << example[1][2];  
}

I hope this would help you.

坦然微笑 2024-11-07 19:30:19

您不能像这样重载 [][] ,因为没有这样的
操作员。你可以重载 [] 来返回一些东西
定义了一个 [] (代理);在最简单的情况下,
double* 这样的东西可以工作,但通常更好,
虽然多一点工作,但要使用完整的类。 (需要添加的地方
例如,边界检查。)

或者,您可以重载 (x,y)。取决于你是谁
问,一种格式或另一种“更好”。 (事实上​​,这是
严格来说是风格问题。)

You can't overload [][] as such, since there isn't such an
operator. You can overload [] to return something which also
has an [] defined on it (a proxy); in the simplest case,
something like a double* will work, but it's usually better,
although a bit more work, to use a full class. (Place to add
bounds checking, for example.)

Alternatively, you can overload (x,y). Depending on who you
ask, one format or the other is "better". (In fact, it's
strictly a question of style.)

冧九 2024-11-07 19:30:19

模板矩阵类

template <uint8_t rows, uint8_t cols, typename T>
class MatrixMxN {
public:
    T* operator[](uint8_t f_row) {
        return &m_val[f_row * cols];
    }
protected:
    T m_val[rows*cols];
};

,这里是3行4列整数类型的矩阵对象。

MatrixMxN<3, 4, int32_t> M;
M[2][3] = 10;
std::cout << M[2][3] << std::endl;

Template matrix class

template <uint8_t rows, uint8_t cols, typename T>
class MatrixMxN {
public:
    T* operator[](uint8_t f_row) {
        return &m_val[f_row * cols];
    }
protected:
    T m_val[rows*cols];
};

and here is object of matrix with 3 row, 4 column and integer type.

MatrixMxN<3, 4, int32_t> M;
M[2][3] = 10;
std::cout << M[2][3] << std::endl;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文