【问题标题】:Operator [] in two dimensional vector二维向量中的运算符 []
【发布时间】:2015-02-23 17:08:08
【问题描述】:

我想在二维向量的情况下创建一个运算符[]。经过搜索,我发现不可能传递两个参数。我如何获得m_matrix[i][j] 的主要值?

相关代码:

class MyMatrix  
{
    public:            // Methods

        MyMatrix();
        ~MyMatrix();

        int operator[] (int n);

    private:          // Attributes

        int m_n;
        int m_m;

        std:: vector <std:: vector <int> > m_matrix;

};

int MyMatrix::operator[](int n, int m)  // in the cpp
{
    if (n>=0 && m>=0 && n<=m_n && m<=m_m)
    {
      return m_matrix[n-1][m-1];
    }
    else
    {   cout<<"******************"<<endl;
        cout<<"No valid index"<<endl;
        cout<<"******************"<<endl;
        return 0;
    }
}

...

mat_test1[2][2]; // for example in the main

这是怎么回事?

【问题讨论】:

  • operator[] 只能接受一个参数,句号。你可以使用operator(),或者让operator[]返回一个实现自己的代理operator[]
  • 您可以改用operator()(size_t, size_t)
  • std::vector&lt;int&gt;&amp; operator[] (int n); 呢?
  • @juanchopanza 为什么?除了执行标准库中已经存在的反模式之外,还有什么变化。
  • @juanchopanza 我批评使用size_t,而不是()。我在自己的回答中提到了这种可能性。

标签: c++ vector operator-keyword


【解决方案1】:

要恢复评论,您可以:

class MyMatrix
{
public:

    // Other methods

    const std::vector<int>& operator[] (int m) const { return m_matrix.at(m); }
    std::vector<int>& operator[] (int m) { return m_matrix.at(m); }

    int operator () (int m, int n) const { return m_matrix.at(m).at(n); }
    int& operator () (int m, int n) { return m_matrix.at(m).at(n); }

private:
    std::vector<std::vector<int>> m_matrix;
};

注意:我使用 at 而不是 [] 来使用来自向量的检查,因此它会为越界访问抛出异常。

然后使用它:

MyMatrix matrix(5, 4); // size of the matrix from constructor

matrix[0][1] = 42; // MyMatrix::operator [] followed by std::vector<int>::operator[]
matrix(2, 2) = 42; // MyMatrix::operator () (int, int);

Live example.

【讨论】:

  • 我很惊讶at 是合适的。您真的认为所有客户端都能够从可能的编程错误中恢复是合理的吗?
  • @JamesKanze:我认为这比 OP 的检查要好。但是assert 会更好。
  • 我没有注意到 OP 的检查。我同意,那更糟。 assert 是必需的。
  • @Jarod42 我尝试了代码,也许我不太理解 'std::vector& MyMatrix::operator[] (int m) { return m_matrix[m]; } int& MyMatrix::operator () (int m, int n) { return m_matrix [m][n]; }' // 在 cpp 中但它不起作用我做错了什么?
  • @Jarod42 感谢您的回复,但如果我想主要获得表达式 cout
【解决方案2】:

有几种方法,但最终都归结为使用 代理。

由于各种原因,矩阵的通常实现不是 std::vector&lt;std::vector&lt;T&gt;&gt;,但只是 std::vector&lt;T&gt;,带有 指数的适当计算。在这种情况下:

class Matrix
{
    int myRows;
    int myColumns;
    std::vector<int> myData;

    class Proxy
    {
        Matrix* myOwner;
        int myRow;
    public:
        Proxy( Matrix* owner, int row )
            : myOwner( owner )
            , myRow( row )
        {
        }
        int& operator[]( int column )
        {
            return myOwner->get( myRow, column );
        }
    };
public:
    Matrix( int rows, int columns )
        : myRows( rows )
        , myColumns( columns )
        , myData( rows * columns )
    {
    }

    int& get( int row, int column )
    {
        assert( 0 <= row && row < myRows
                && 0 <= column && column < myColumns );
        return myData[ row * myColumns + column ];
    }

    Proxy operator[]( int row ) { return Proxy( this, row ); }
};

事实上,您需要更多的重载(可能还有两个代理) 处理 const 和非常量重载。但这是一般模式 对于这样的事情。

也请注意,有两个关于此类重载的约定。 一种是说[] 返回一个投影,并且正确 将索引处理成多维结构的解决方案是 重载operator()(可以取任意数量的 参数)。我个人更喜欢[][] 解决方案,但是这个 偏好不是普遍的;很多人更数学 背景更喜欢使用()

【讨论】:

  • 你能解释一下什么是代理吗? (我是初学者对不起)
  • @Laura 代理正是我展示的;一个类代替另一个类,以提供额外的功能。两个最常见的用途(我认为)是支持多个[],就像这里一样,以及在返回类型上模拟重载。
猜你喜欢
  • 2018-10-16
  • 2017-10-30
  • 2010-09-19
  • 1970-01-01
  • 1970-01-01
  • 2014-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多