为什么在重载 [] 运算符时无法 return const 引用
Why is it not possible to return a const reference while overloading the [] operator
我们以这段代码为例
#include <iostream>
using namespace std;
struct valStruct {
double& operator[](int i){return values[i];}; //line 6
double operator[](int i) const {return values[i];}; //line 7
double values[4];
};
int main () {
valStruct vals = {0,1,2,3};
cout << "Value before change" << endl;
for ( int i = 0; i < 3; i++ ) {
cout << "vals[" << i << "] = "<< vals[i] << endl;
}
vals[1] = 2.2; // change 2nd element
cout << "Value after change" << endl;
for ( int i = 0; i < 3; i++ ) {
cout << "vals[" << i << "] = "<< vals.values[i] << endl;
}
return 0;
}
我知道第 6 行(请参阅代码中的注释)允许将值写入(和读取!?)数组 values
中的索引,而第 7 行仅读取该值。
我理解第 7 行中 const 声明的必要性,因为它可以防止在无意的情况下更改值(尽管我不明白自第 6 行以来如何存在),但我的问题是,为什么我不能将此行写为
double& operator[](int i) const {return values[i];}; //line 7
抛出错误:binding reference of type ‘double&’ to ‘const double’ discards qualifiers
.
这也提出了一个问题,为什么我们需要第 7 行,因为第 6 行存在并且可以写和读。
编辑:
我理解 const func() const [在此处建议][1] 的概念,但我不明白这如何回答我的问题。我不明白回答我问题的两个答案所解释的机制。
我现在明白了,第二行是处理我函数的常量对象所需要的。
我也明白当我有一个 func() const 时,它隐含地使成员成为 const。这意味着 returned 值需要保持不变,这就是为什么这不起作用
´double& operator[](int i) const { return values[i]; };´
虽然这样做
´const double& operator[](int i) const { return values[i]; };´
[1]:
why do we need line 7 at all since line 6 exists and can do both writing and reading.
我们需要第 7 行来处理 const
个对象。第 6 行不能用于 const
类型 valStruct
的对象。这是因为const
class对象只能显式调用const成员函数,而第6行重载的operator[]
没有被标记为const成员函数。所以它不能用在 valStruct
类型的 const 对象上。因此,我们需要第 7 行将重载的 operator[]
“标记”为 const 成员函数。有关此的更多信息,请参见 here.
现在,如果您将第 7 行中的 return 类型更改为 double&
,那么问题是您在这里将 operator[]
重载为 const成员函数。这意味着数据成员也是const
。并且由于我们无法将 "lvalue reference to non-const object" 绑定到 const
对象,所以我们得到了上述错误。例如,
const double d = 43.4;
double& ref = d;//here we'll get the same error
情况(您收到错误的原因)与上面给定的代码段类似。
要解决(摆脱)这个错误,我们需要将 return 类型从 double&
更改为 const double&
。
this
引用 const
合格成员函数中的 const
对象。这里:
double& operator[](int i) const {return values[i];}; //line 7
您正在尝试 return 对 this->values[i];
的引用。当对象是 const
.
时,该引用不能是 non-const
通常提供两个重载:
double& operator[](int i) { return values[i]; }; // 1
const double& operator[](int i) const { return values[i]; }; // 2
// ^ returned reference is const
// ^ current object is const
第一个只能在 non-constant 对象上调用。当对象为 const
时,则调用第二个:
valStruct a;
double x = a[0]; // calls 1
const valStruct b;
double x = b[0]; // calls 2
因为复制 double
并不昂贵,您可以 return double
而不是参考。
This also raises the question of why do we need line 7
因为没有 const operator[]
你将无法调用 b[]
.
我们以这段代码为例
#include <iostream>
using namespace std;
struct valStruct {
double& operator[](int i){return values[i];}; //line 6
double operator[](int i) const {return values[i];}; //line 7
double values[4];
};
int main () {
valStruct vals = {0,1,2,3};
cout << "Value before change" << endl;
for ( int i = 0; i < 3; i++ ) {
cout << "vals[" << i << "] = "<< vals[i] << endl;
}
vals[1] = 2.2; // change 2nd element
cout << "Value after change" << endl;
for ( int i = 0; i < 3; i++ ) {
cout << "vals[" << i << "] = "<< vals.values[i] << endl;
}
return 0;
}
我知道第 6 行(请参阅代码中的注释)允许将值写入(和读取!?)数组 values
中的索引,而第 7 行仅读取该值。
我理解第 7 行中 const 声明的必要性,因为它可以防止在无意的情况下更改值(尽管我不明白自第 6 行以来如何存在),但我的问题是,为什么我不能将此行写为
double& operator[](int i) const {return values[i];}; //line 7
抛出错误:binding reference of type ‘double&’ to ‘const double’ discards qualifiers
.
这也提出了一个问题,为什么我们需要第 7 行,因为第 6 行存在并且可以写和读。
编辑:
我理解 const func() const [在此处建议][1] 的概念,但我不明白这如何回答我的问题。我不明白回答我问题的两个答案所解释的机制。
我现在明白了,第二行是处理我函数的常量对象所需要的。
我也明白当我有一个 func() const 时,它隐含地使成员成为 const。这意味着 returned 值需要保持不变,这就是为什么这不起作用
´double& operator[](int i) const { return values[i]; };´
虽然这样做
´const double& operator[](int i) const { return values[i]; };´
[1]:
why do we need line 7 at all since line 6 exists and can do both writing and reading.
我们需要第 7 行来处理 const
个对象。第 6 行不能用于 const
类型 valStruct
的对象。这是因为const
class对象只能显式调用const成员函数,而第6行重载的operator[]
没有被标记为const成员函数。所以它不能用在 valStruct
类型的 const 对象上。因此,我们需要第 7 行将重载的 operator[]
“标记”为 const 成员函数。有关此的更多信息,请参见 here.
现在,如果您将第 7 行中的 return 类型更改为 double&
,那么问题是您在这里将 operator[]
重载为 const成员函数。这意味着数据成员也是const
。并且由于我们无法将 "lvalue reference to non-const object" 绑定到 const
对象,所以我们得到了上述错误。例如,
const double d = 43.4;
double& ref = d;//here we'll get the same error
情况(您收到错误的原因)与上面给定的代码段类似。
要解决(摆脱)这个错误,我们需要将 return 类型从 double&
更改为 const double&
。
this
引用 const
合格成员函数中的 const
对象。这里:
double& operator[](int i) const {return values[i];}; //line 7
您正在尝试 return 对 this->values[i];
的引用。当对象是 const
.
通常提供两个重载:
double& operator[](int i) { return values[i]; }; // 1
const double& operator[](int i) const { return values[i]; }; // 2
// ^ returned reference is const
// ^ current object is const
第一个只能在 non-constant 对象上调用。当对象为 const
时,则调用第二个:
valStruct a;
double x = a[0]; // calls 1
const valStruct b;
double x = b[0]; // calls 2
因为复制 double
并不昂贵,您可以 return double
而不是参考。
This also raises the question of why do we need line 7
因为没有 const operator[]
你将无法调用 b[]
.