如何为多维向量重载下标运算符?

时间:2014-09-07 01:23:48

标签: c++ templates matrix

这是我目前的Matrix课程:

template<class T>
class Matrix
{
    public:
        Matrix() { }
        Matrix(int z, int x, int y) 
        { 
            matrix.resize(z); 
            for (unsigned int i = 0; i < matrix.size(); i++)
                matrix[i].resize(x);

            for (unsigned int i = 0; i < matrix.size(); i++)
            {
                for (unsigned int j = 0; j < matrix[i].size(); j++)
                    matrix[i][j].resize(y);
            }
            Fill(0);
        }

        int dim1() { return matrix.size(); }
        int dim2() { return matrix[0].size(); }
        int dim3() { return matrix[0][0].size(); }

        void Fill(int n);
        bool Set(int z, int x, int y, T value);

        class Row
        {
            std::vector<std::vector<T>> m_row;
            public:
                Row(std::vector<std::vector<T>> row) : m_row(row) { }
                class Column
                {
                    std::vector<T> m_column;
                    public:
                        Column(std::vector<T> column) : m_column(column) { }
                        T& operator [] (int index) { return this->m_column[index]; }
                };
                Column operator [] (int index) { return Column(m_row[index]); }
        };

        Row operator [] (int index) { return Row(matrix[index]); }

    private:
        std::vector<std::vector<std::vector<T>>> matrix;
};

template<class T>
void Matrix<T>::Fill(int n)
{
    for (unsigned int i = 0; i < matrix.size(); i++)
        for (unsigned int j = 0; j < matrix[0].size(); j++)
            for (unsigned int k = 0; k < matrix[0][0].size(); k++)
                matrix[i][j][k] = n;
}

template<class T>
bool Matrix<T>::Set(int z, int x, int y, T value)
{
    if (z < matrix.size() && x < matrix[0].size() && y < matrix[0][0].size())
    {
        matrix[z][x][y] = value;
        return true;
    }
    else
        return false;
}

一切正常,除了以下代码中注释掉的一行

Matrix<int> m(3, 10, 20);

m.Set(2, 4, 10, 42);

// m[2][4][10] = 42;

std::cout << "base layer:  " << m.dim1() << std::endl;
std::cout << "layer x:    " << m.dim2() << std::endl;
std::cout << "layer y:    " << m.dim3() << std::endl;
std::cout << "\nm[2][4][10] = " << m[2][4][10] << std::endl;

当我做“m [2] [4] [10] = 42”时,而不是“Set(x,x,x,x)”函数,“cout&lt;&lt; m [2] [ 4] [10]“返回0而不是42。 它对我来说没有意义,我真的想使用下标来设置值。

编辑:我更改了问题标题以使其更有意义。

2 个答案:

答案 0 :(得分:0)

Row operator [] (int index) { return Row(matrix[index]); }

此处的返回类型指定一个返回 by-value 的函数。因此,返回matrix[index]的副本,并且对返回值执行的任何后续操作仅影响副本,但不影响原始对象。

总是,解决方案是返回左值引用。但是,由于你如何返回索引,这仍然无济于事。 Row(...)构造一个Row的临时实例,它与您应该返回的Row对象分开 - 它实际上是它的副本。没有必要使用这种语法,直接使用return:

Row& operator [] (int index) { return matrix[index]; }

请注意,这不仅适用于此功能,也适用于返回Column的功能。

答案 1 :(得分:0)

我今天再次查看了我的代码,并意识到我需要的是双向的参考。所以我将Row和Column变量更改为引用,测试它并且它起作用。

class Row
{
    std::vector<std::vector<T>>& m_row;
    public:
        Row(std::vector<std::vector<T>>& row) : m_row(row) { }
        class Column
        {
            std::vector<T>& m_column;
            public:
                Column(std::vector<T>& column) : m_column(column) { }
                T& operator [] (int index) { return this->m_column[index]; }
        };
        Column operator [] (int index) { return Column(m_row[index]); }
};

Row operator [] (int index) { return Row(matrix[index]); }

我不想使用指针来避免记忆韭菜,这是我最初的解决方案,可能是一个糟糕的解决方案。我认为这应该是一个很好的下标超载。