如何解决当将`[]`运算符重载到容器类时,`&`的重要性是什么?
假设我有这个简单的容器类
class Array{
private:
int m_l{};
int *m_d{};
public:
Array() = default;
Array(int len)
: m_l{len}
{
assert(len >= 0);
if (len > 0)
{
m_d = new int[len]{};
}
}
~Array(){
delete[] m_d;
}
// -------------------------------------------
int& operator[](int i){
assert(i >= 0 && i <= m_l && "Index in operator [] out of range");
return m_d[i];
}
//--------------------------------------------
};
特别是
int& operator[](int i)
{
assert(i >= 0 && i <= m_l && "Index in operator [] out of range");
return m_d[i];
}
我已经重载了[]
运算符以获取下标,我只是在学习有关运算符重载和容器类的信息。
Array arr{5};
arr[0] = 32;
arr[1] = 34;
std::cout << arr[0];
32
代码按预期编译并执行,但是如果我从函数中删除&
,就可以做到
int operator[](int i)
{
assert(i >= 0 && i <= m_l && "Index in operator [] out of range");
return m_d[i];
}
编译器抛出错误
在操作数赋值左侧需要左值
为什么会发生此错误,&
在函数中的意义是什么?
解决方法
没有下标运算符重载中的引用,您正在从函数中返回一个临时的右值。右值不能出现在赋值操作的左侧。
特别是,当您编写arr[0]
时,在重载中没有引用的情况下,该引用只会返回一个整数(无论arr [0]的值是什么)。
Array arr{5};
arr[0]; //Without the reference,this returns 5.
5 = 32; //Written out,this is what the expression turns to.
5是无法分配的右值-5 = 32
是什么意思?在引用重载的情况下,您将对数组的第一个元素(即左值)返回一个引用(存储位置)。阅读this可能有助于您更好地理解它。
&
中的int&
意味着您的operator[]
向{{返回一个引用(即别名,通常实现为内存地址) 1}}变量。一旦绑定到变量,分配给引用的任何值都将分配给它引用的变量。
如果没有int
,则您的&
将返回operator[]
的副本(即值)。
当函数返回值而不是引用时,编译器将创建一个临时变量来保存该值。该临时文件只存在,直到创建它的语句结束。该临时变量称为rvalue,即在赋值右侧使用的值。要保留更长的值,调用者必须将其分配给另一个变量。
诸如命名变量,对变量的引用等是lvalue,即它们可以在分配的左侧使用。右值不能在左侧使用,只能在右侧使用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。