为容器 class 重载 `[]` 运算符时,`&` 的重要性是什么?
What is the importance of `&` when overloading the `[]` operator for a container class?
假设我有这个简单的容器class
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];
}
我已经重载了 []
运算符来获取下标,我只是在学习运算符重载和容器 classes.
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];
}
编译器抛出错误
lvalue required as left of operand assignment
为什么会出现这个错误,函数中&
的意义是什么?
如果没有下标运算符重载中的引用,您将return从函数中获取一个临时右值。右值不能出现在赋值操作的左侧。
具体来说,当你写 arr[0]
时,如果你的重载中没有引用,那只会 return 一个整数(无论 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
是什么意思?通过引用重载,您正在 return 对数组的第一个元素(左值)进行引用(内存位置)。阅读 this 可能会帮助您更好地理解它。
int&
中的&
表示您的operator[]
return是一个引用(即别名,通常实现作为内存地址)到 int
变量。一旦绑定到变量,分配给引用的任何值都会分配给它所引用的变量。
如果没有 &
,您的 operator[]
将 return copy(即值)int
相反。
当函数 return 是一个值而不是引用时,编译器会创建一个临时变量来保存该值。该临时文件只存在于创建它的语句结束之前。该临时变量称为 rvalue,即在赋值的 right-hand 端使用的值。要更长时间地保留该值,调用者必须将其分配给另一个变量。
诸如命名变量、对变量的引用等都是 lvalue,即它们可以在赋值的 left-hand 端使用。右值不能用在 left-hand 端,只能用在 right-hand 端。
假设我有这个简单的容器class
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];
}
我已经重载了 []
运算符来获取下标,我只是在学习运算符重载和容器 classes.
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];
}
编译器抛出错误
lvalue required as left of operand assignment
为什么会出现这个错误,函数中&
的意义是什么?
如果没有下标运算符重载中的引用,您将return从函数中获取一个临时右值。右值不能出现在赋值操作的左侧。
具体来说,当你写 arr[0]
时,如果你的重载中没有引用,那只会 return 一个整数(无论 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
是什么意思?通过引用重载,您正在 return 对数组的第一个元素(左值)进行引用(内存位置)。阅读 this 可能会帮助您更好地理解它。
int&
中的&
表示您的operator[]
return是一个引用(即别名,通常实现作为内存地址)到 int
变量。一旦绑定到变量,分配给引用的任何值都会分配给它所引用的变量。
如果没有 &
,您的 operator[]
将 return copy(即值)int
相反。
当函数 return 是一个值而不是引用时,编译器会创建一个临时变量来保存该值。该临时文件只存在于创建它的语句结束之前。该临时变量称为 rvalue,即在赋值的 right-hand 端使用的值。要更长时间地保留该值,调用者必须将其分配给另一个变量。
诸如命名变量、对变量的引用等都是 lvalue,即它们可以在赋值的 left-hand 端使用。右值不能用在 left-hand 端,只能用在 right-hand 端。