错误 C2106:'=':左操作数必须是 l 值
error C2106: '=' : left operand must be l-value
看看关于错误C2106的其他问题,我仍然不知道我的代码有什么问题。在编译时,我得到以下错误:
c: \driver.cpp(99):错误C2106:"=":左操作数必须是l-value
c: \driver.cpp(169):错误C2106:"=":左操作数必须是l-value
代码行如下:
payroll.at(i) = NULL; //Line 99
payroll.at(count++) = ePtr; //Line 169
我不明白为什么会出现这个错误。在这个项目中,我将driver.cpp从一个雇员对象指针数组更改为我制作的自定义Vector模板。我声明向量如下。。。
//Declare an Vector to hold employee object pointers
MyVector <employee*> payroll;
任何帮助都将不胜感激。。。
引发此错误的原因与您不能执行以下操作的原因相同:
36 = 3;
您的Vector::at
版本应该返回引用,而不是值
Lvalue之所以被称为Lvalue,是因为它们可以出现在赋值的左边。R值不能出现在左侧,这就是为什么我们称它们为右值。不能将3
分配给36
,因为36
不是左值,而是一个右值,一个临时值。它没有内存地址。出于同样的原因,不能将NULL
分配给payroll.at(i)
。
你的定义:
template <class V> V MyVector<V>::at(int n)
应该是什么:
template<typename V> V& MyVector::at(std::size_t n)
template<typename V> const V& MyVector::at(std::size_t n) const
消息说您试图分配给一个不是左值的表达式。对于内置类型,您只能分配给lvalues(这就是名称的来源:lvalue=可以位于赋值运算符的左侧的值,而rvalue=必须位于赋值运算符右侧右侧的值)。
那么什么是左值或右值呢?考虑以下代码:
int a;
a = 3;
在这个赋值中,a
是一个左值(如果不是,编译器会抱怨)。也就是说,表达式a
指的是可以被修改的对象。另一方面,3
是一个右值,也就是说,基本上是一个值。当然,您不能分配给3
;编译器会抱怨语句CCD_ 11与您在代码中得到的消息完全相同。
因此,作为第一近似,左值指定对象,而右值指定值。注意,对于表单的分配也是如此
a = b;
其中CCD_ 12也是一个变量。这里发生的是所谓的左值到右值的转换:分配的不是对象b
,而是它的当前值。
现在考虑以下情况:
int f();
f() = 3;
在这里,您可能会争辩说函数f
确实返回了一个对象(如果您使用某种用户定义的类型,您甚至可以看到它的构造/销毁)。但是编译器仍然会对您收到的消息进行抱怨。为什么?
好吧,即使您认为f
返回一个对象,它也是一个临时对象,会立即消失。因此,分配一个值没有多大意义,因为之后无论如何都不能对它做任何事情。
因此,这里有第二条规则:
只要有一个表达式生成临时对象,C++就会将该表达式定义为右值。
现在我们来讨论MyVector::at()
的定义,您没有显示它,但根据错误消息,它可能看起来像这样:
template<typename T>
T MyVector<T>::at(int i)
{
return data[i];
}
它的形式与上面的f
基本相同,因为它还返回一个T
(在您的情况下是employee*
)。这就是编译器抱怨的原因。
这种抱怨是有帮助的:即使编译器不会抱怨,代码也不会说出你几乎可以肯定的意图。return
语句返回对象data[i]
的副本。因此,如果payment.at(i)=NULL;
已经编译了语句,那么实际会发生以下情况:
- 内部对象
data[i]
(或您在代码中调用它的方式)被复制,并返回临时副本 - 指定临时复制的语句,但保持
MyVector
中的原始对象不变 - 临时副本会被销毁,不会留下您的作业痕迹
这几乎肯定不是你想要的。您想要更改内部对象。要做到这一点,您必须向该对象返回引用。引用引用的是初始化时使用的对象,而不是复制。相应地,引用,即使被返回,也是一个左值(由于C++11,还有第二种类型的引用表现不同,但我们在这里不需要关心这一点)。修正后的函数会读取
template<typename T>
T& MyVector<T>::at(int i)
{
return data[i];
}
有了这个定义,payment.at(i)=NULL;
不仅可以编译,而且可以实际执行您想要的操作:将payment
中内部存储的第26个CCD_指针更改为NULL
。
您的函数MyVector::at(unsigned)
可能没有正确声明,看起来像这样:
T MyVector::at(unsigned i) { /* implementation detail */ }
你想要的是它看起来像这样:
T& MyVector::at(unsigned i) { /* implementation detail */ }
注意reference参数(&),它将通过引用返回任何元素,并允许表达式用作l值。
真正的问题是你为什么不使用std::vector
?
c++中的术语l-value表示"左值"的类型不正确。由于您在它上使用赋值运算符,因此要成为正确的类型,它必须是一个可以被赋予新值的值,这意味着它不能是常量。很可能,对payroll.at()
的调用返回的是一个常数值,而不是对实际值的引用。尝试为其分配一个新值将导致l-value错误。
- 警告处理为错误这里有什么问题
- "error: no matching function for call to"构造函数错误
- boost::进程间消息队列引发错误
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- QT在错误的班级中寻找空位
- vector.resize()中的分配错误
- 代码在main()中运行,但在函数中出现错误
- 释放错误后堆使用
- (C++)分析树以计算返回错误值的简单算术表达式
- Project Euler问题4的错误解决方案
- 我的字符计数代码计算错误.为什么
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 尝试导入pybind-opencv模块时出现libgtk错误
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 在某些循环内使用vector.push_back时出现分段错误
- MSVC多行宏编译器错误
- 错误 C2106:'=':左操作数必须是斐波那契数列中的 l 值,方法是动态规划 C++
- 错误 C2106:'=':左操作数必须是 l 值
- 错误 C2106:'=':左操作数必须是 l 值 C++二叉树