左值作为赋值的左操作数 - 数组

0 c++ arrays operator-overloading

下面是错误所在的代码片段

a[i][j] = m[i][j] + w[i][j];
Run Code Online (Sandbox Code Playgroud)

返回错误

左值作为赋值的左操作数

我找不到适用于数组的答案,我的Matrix定义如下:

Matrix::Matrix() {
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            coords[i][j] = 0.0f;
}

const Matrix operator+(const Matrix &m, const Matrix &w) {
    Matrix a;
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 4 ; j++)
            a[i][j] = m[i][j] + w[i][j];  // <----- error
    return a;
}
Run Code Online (Sandbox Code Playgroud)

这是运算符[]如何通过引用返回

const Vector Matrix::operator[](int i) const{
    switch(i)
    {
    case 0: return Vector (coords[i][0], coords[i][1], coords[i][2]);
    case 1: return Vector (coords[i][0], coords[i][1], coords[i][2]);
    case 2: return Vector (coords[i][0], coords[i][1], coords[i][2]);
    }
}
Run Code Online (Sandbox Code Playgroud)

Jos*_*eld 11

该错误实际上是" 左值作为赋值的左值 ".

这意味着你a[i][j]正在给你一个临时对象.当您按值返回函数时会发生这种情况.按值返回的函数调用是一个rvalue表达式,并且不能将rvalue表达式用作赋值的左操作数.您需要更改的执行operator[]上都Matrix和助手类Matrix::operator[]返回,使他们引用返回.通过引用返回的函数调用是左值表达式,允许您为其赋值.

template <typename T>
Vector<T>& Matrix<T>::operator[](int index) { ... }
template <typename T>
T& Vector<T>::operator[](int index) { ... }
Run Code Online (Sandbox Code Playgroud)

当然,这是有道理的.如果您的operator[]s没有通过引用返回,那么如何分配它们返回的值对于Matrix?的内容有什么影响?


为了回应您的编辑:

你的课程设计有问题.的Matrix类似乎存储3×3阵列的float叫做coords.但是,在使用时Matrix::operator[],它会将值从一行复制coordsVector对象中.它们是副本.然后Vector按值返回,将值Vector及其包含的值复制出函数.您对返回的内容所做的任何操作Vector都只会影响该副本.

除此之外,你的switch陈述完全没有意义.每个案例都完全一样.您只需要使用i数组索引而不是打开它.

此外,如果您打算允许那些打电话的人operator[]修改您的内容Matrix,那么该operator[]功能一定不能const.

有一些替代方案可以解决您的问题.首先是返回一个float*而不是废弃你的计划Vector:

float* Matrix::operator[](int i) {
    return coords[i];
}
Run Code Online (Sandbox Code Playgroud)

这是一个非常简单的解决方案,但确实涉及传递原始指针.原始指针可以像数组一样使用,允许您使用语法m[i][j].

你可以像Eigen库那样做,而是提供一个带有operator()两个参数,行索引和列索引:

float& Matrix::operator()(int i, int j) {
    return coords[i][j];
}
Run Code Online (Sandbox Code Playgroud)

请注意,float通过引用返回:float&.这意味着可以从调用之外进行修改operator().在这里,您将使用索引行和列m(i, j).