如何在常量数组中重载“[] []运算符”?

时间:2014-11-26 14:19:41

标签: c++ arrays subscript

被困在这一段时间了。我有一个3x3矩阵类的数学库。它曾经是动态的,使用指针和分配创建的内存。但由于它总是3x3我决定改变它,但现在我不能使用[] []来获取我的数组的值。我正在使用代理类!

class mat3 {
    private:
        double arr[3][3];

    public:
        mat3();
        mat3(double, double, double, double, double,
            double, double, double, double);

                    //Proxy class
        class Proxy {
            private:
                double arr[3];
            public:
                Proxy(const double _arr[3]) { arr = _arr; }
                double& operator[] (const int index) {
                    return arr[index];
                }
                const double& operator[] (const int index) const{
                    return arr[index];
                }
        };

        const Proxy operator[] (const int index) const{
            return Proxy(arr[index]);
        }

        Proxy operator[] (const int index) {
            return Proxy(arr[index]);
        }

现在arr = _arr我得到编译器错误:错误:表达式必须是可修改的Ivalue

我做错了什么?我如何实现这一目标?

3 个答案:

答案 0 :(得分:1)

当您将数组作为参数传递时,它会转换为指针,因此您的构造函数与Proxy(const double *_arr) { arr = _arr; }相同,而且非法。

此外,您希望在mat3中返回对原始值的引用。因此,更改代理以使用指针加倍:

class Proxy {
private:
   double *arr;
...
};

答案 1 :(得分:1)

您不需要代理类,您可以这样做:

class mat3
{
    using row_type = double [3];
public:
    mat3();
    mat3(double, double, double, double, double, double, double, double, double);

    const row_type& operator[](const int index) const { return arr[index]; }
    row_type& operator[](const int index) { return arr[index]; }

private:
    row_type arr[3]; // or double arr[3][3];
};

另请注意,使用std::array<std::array<double, 3>, 3> arr;编辑C-array的代码会更直观。

如果您真的希望拥有Proxy课程,可以使用:

class mat3
{
    using row_type = double[3];

public:
    mat3();
    mat3(double, double, double, double, double, double, double, double, double);

    class Proxy
    {
    private:
        row_type& arr; // or double (&arr)[3];

    public:
        explicit Proxy(row_type& arr) : arr(arr) {}
        double& operator[](const int index) { return arr[index]; }
        const double& operator[](const int index) const { return arr[index]; }
    };

    const row_type& operator[](const int index) const { return arr[index]; }

    row_type& operator[](const int index) { return arr[index]; }

private:
    row_type arr[3]; // or double arr[3][3];
};

答案 2 :(得分:1)

令人惊讶的是,这是有效的(我没想到):

#include <iostream>

struct matrix
{
    typedef double ((&reference)[3])[3]; // define a reference type to a 3x3 array

    double array[3][3];

    operator reference() // implicit conversion to 3x3 array reference
    {
        return array;
    }

    void dump()
    {
        for(unsigned x = 0; x < 3; ++x)
            for(unsigned y = 0; y < 3; ++y)
                std::cout << array[x][y] << '\n';
    }
};

int main()
{
    matrix m;

    for(unsigned x = 0; x < 3; ++x)
        for(unsigned y = 0; y < 3; ++y)
            m[x][y] = x * y; // seems to work okay!!!

    m.dump();
}