赋值-数组的左操作数需要左值
lvalue required as left operand of assignment - Array
下面是错误所在的代码片段,行
a[i][j] = m[i][j] + w[i][j];
返回错误
赋值的左操作数所需的左值
我找不到适用于数组的答案,我的矩阵定义如下:
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;
}
这是接线员[]我如何通过参考返回
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]);
}
}
错误实际上是"赋值的左操作数需要左值"。
这意味着您的a[i][j]
正在为您提供一个临时对象。当您按值从函数返回时,就会发生这种情况。按值返回的函数调用是右值表达式,并且不能将右值表达式用作赋值的左操作数。您需要更改Matrix
和Matrix::operator[]
返回的helper类上operator[]
的实现,以便它们通过引用返回。通过引用返回的函数调用是一个左值表达式,并允许您为其赋值
template <typename T>
Vector<T>& Matrix<T>::operator[](int index) { ... }
template <typename T>
T& Vector<T>::operator[](int index) { ... }
当然,这是有道理的。如果您的operator[]
没有通过引用返回,那么分配给它们返回的值会对Matrix
的内容产生什么影响?
回应您的编辑:
你的课设计有问题。Matrix
类似乎存储一个称为coords
的3乘3的float
数组。但是,当使用Matrix::operator[]
时,它会将coords
的一行中的值复制到Vector
对象中。它们是副本。然后按值返回Vector
,该值将Vector
及其包含的值复制到函数之外。对返回的Vector
所做的任何操作都只会影响该副本。
除此之外,您的switch
语句完全没有意义。每个案例都完全相同。你只需要使用i
作为数组索引,而不需要打开它
此外,如果要允许调用operator[]
的人修改Matrix
的内容,则operator[]
函数不能是const
。
有几个替代方案可以解决你的问题。第一种是只返回一个float*
,然后用Vector
:取消您的计划
float* Matrix::operator[](int i) {
return coords[i];
}
这是一个非常简单的解决方案,但确实需要传递一个原始指针。原始指针可以像数组一样使用,允许使用语法m[i][j]
。
您可以执行与Eigen库相同的操作,而是提供一个operator()
,它接受两个参数,行索引和列索引:
float& Matrix::operator()(int i, int j) {
return coords[i][j];
}
请注意,float
是通过引用返回的:float&
。这意味着它可以在对operator()
的调用之外进行修改。在这里,您可以使用m(i, j)
对行和列进行索引。
这意味着您的[]
运算符返回的值没有不能用于赋值的地址。它笔直向前。
什么是Vector
?
问题可能始于什么Matrix::operator[]
退货。为了使[][]
语法正常工作,它必须返回一些可以应用第二个[]
的代理类型,并且将返回对矩阵中所需元素的引用。做这件事的通常方法(至少对我来说)是定义Matrix
:中的"setter"answers"getter"
void set( int i, int j, double new_value )
{
myData[ getIndex( i, j ) ] = new_value;
}
double get( int i, int j ) const
{
return myData[ getIndex( i, j ) ];
}
然后使用两个代理(矩阵中的嵌套类):
class Proxy2D
{
Matrix* myOwner;
int myIndex1;
int myIndex2;
public:
Proxy2D( Matrix& owner, int index1, int index2 )
: myOwner( &owner )
, myIndex1( index1 )
, myIndex2( index2 )
{
}
void operator=( double new_value ) const
{
myOwner->set( myIndex1, myIndex2, new_value ):
}
operator double() const
{
return myOwner->get( myIndex1, myIndex2 );
}
};
class Proxy1D
{
Matrix* myOwner;
int myIndex;
public:
Proxy1D( Matrix& owner, int index )
: myOwner( &owner )
, myIndex( index )
{
}
Proxy2D operator[]( int index2 ) const
{
return Proxy2D( *myOwner, myIndex, index2 );
}
};
Proxy1D operator[]( int index1 )
{
return Proxy1D( *this, index1 );
}
在实践中,您还希望返回const变量通过CCD_ 36。当然,CCD_ 37不需要CCD_ 38的过载;这个隐式转换就足够了。
在不明显的情况下,Matrix::getIndex
做边界检查,然后计算基础中的实际索引包含数据的CCD_ 40。
由于您返回了一个新构建的Vector
对象来表示一列(或行,这并不重要),因此此Vector负责更新原始Matrix实例中的一个条目,这有点棘手,但很容易解决:
您必须实现另一个VectorRef
类,它不通过值而是通过引用来表示向量,因此可以用于访问lvalues的组件。这意味着,它不包含作为值的数字,而是作为引用,并在构造函数中接受这些引用。为了保持简单,您可以使用指向第一个组件(后面是其他组件)的指针:
class VectorRef {
float *coords;
public:
VectorRef(float *coords) : coords(coords) {}
float & operator[](int i) { return coords[i]; }
};
然后,在矩阵的operator[]
中构造这样一个"参考对象":
VectorRef Matrix::operator[](int i) {
return VectorRef (coords[i]);
}
要将VectorRef
也用作Vector
,请提供转换运算符:
// (within VectorRef:)
operator Vector() const { return Vector(coords[0], coords[1], coords[2]); }
这应该会让事情看起来毫无意义。
或者,如果您总是访问矩阵中的元素,而不是整个列,只需直接在矩阵的operator[]
中返回列指针:
float * Matrix::operator[](int i) {
return coords[i];
}
写入mat[x][y]
时,这将首先访问具有mat[x]
的浮点指针,然后访问该列的第y
个元素,该元素是左值。
- 需要左键作为赋值的左操作数?? 在链表中添加Add_End、删除和Delete_Front?
- 作为赋值(增加引用变量)C++的左操作数所需的左值
- C++ - 左操作数作为赋值的左操作数
- 当我尝试构建此程序时,出现此错误:需要左键作为赋值的左操作数
- 添加数组元素:需要左键作为赋值的左操作数
- 对条件表达式结果的赋值(其中第二个和第三个操作数是相同类型和值类别的变量)是否仍然存在?
- 在 c 程序中需要左操作数作为赋值的左操作数
- 基本类型变量的赋值计算序列,右操作数引发异常
- 需要左值作为赋值错误的左操作数通过 if 语句
- 在 C++ 中需要左键作为赋值错误的左操作数
- 错误:左值需要作为赋值的左操作数
- 强制函数仅作为赋值操作数调用
- Geany c++,错误为“赋值的左操作数需要左值”
- 运算符重载所需的左值作为赋值的左操作数
- 气泡排序中赋值c++的左操作数需要左值
- 错误:使用四进制和随机数生成器进行赋值时,左值需要作为左操作数
- 不能赋值:左键需要作为赋值的左操作数
- 错误:左值需要作为赋值 C++ 的左操作数
- 左值需要作为赋值的左操作数(while 循环)
- 左键需要作为赋值的左操作数?查看其他线程无济于事