如何更改重载运算符以返回值而不是引用?
#include <iostream>
using namespace std;
class IntList
{
private:
int list[1];
public:
IntList() {list[0] = 0;}
int& operator[] (const int index) {return list[index];}
};
int main()
{
IntList list;
cout << list[0] << endl;
list[0] = 1;
cout << list[0] << endl;
return 0;
}
答案 0 :(得分:3)
int operator[] (const int index){}
^^^^^
只需删除&
即可。完成后,您无法使用它为数组元素赋值。
返回引用和非引用之间的区别
正如您在operator []
返回引用时注意到的那样,它可以在赋值的左侧使用。这是可能的,因为当您通过引用返回时,operator []
的返回值是l值。引用被视为l值,因为您可以引用存储在内存中并具有地址的变量
当operator []
按值返回时,表达式list[0] = 1;
最终会将 [#] 评估为类似的内容,
1=1;
这是不合逻辑的,因为1
不是l值,编译器将生成左操作数必须为l值的诊断。
[#]假设下标0处元素的值为1 :
答案 1 :(得分:1)
您只需删除&
就可以完成此操作,这样您就可以了
int operator[] (const int index){}
。
但是,正如您所注意到的那样,问题是您无法在没有编译错误的情况下分配它,因为索引运算符不再返回l值。所以我认为你应该考虑为什么要返回一个值而不是一个引用。您可能需要一种模式,其中索引运算符不能用于分配给对象,可能是某种只读类型对象。你的另一个选择是有一个单独的函数来设置它,因为索引操作符不能再用来做那个
答案 2 :(得分:0)
在您的代码示例中,您正在使用赋值,这需要您返回引用。
list[0] = 1;
list.operator[](0) = 1;
int& xref = list.operator[](0);
(xref) = 1; // <-- changed the value of list element 0.
鉴于您希望operator [](int index)返回一个值,这将转换为:
int x = list.operator[](0);
x = 1; <-- you changed x, not list[0].
如果你想让operator [](int index)返回一个值但是list [0] = 1仍然有效,那么你需要提供两个版本的运算符,这样编译器就可以确定哪个行为你试图在给定的电话中调用:
// const member, returns a value.
int operator[] (const int index) const {return list[index];}
// non const member, which returns a reference to allow n[i] = x;
int& operator[] (const int index) {return list[index];}
请注意,它们必须因返回类型和成员常量而不同。
#include <iostream>
using namespace std;
class IntList
{
private:
int list[1];
public:
IntList() {list[0] = 0;}
int operator[] (const int index) const { return list[index]; }
int& operator[] (const int index) {return list[index];}
};
int main(int argc, const char** argv)
{
IntList list;
cout << list[0] << endl;
list[0] = 1;
int x = list[0];
cout << list[0] << ", " << x << endl;
return 0;
}