我从 std::vector 继承了我的类。现在我想重载 []-operator。
当我尝试为我的 vector 分配一个新值时,例如v[0]=5,
我应该收到消息 OK
。
这是我的代码(我知道,这没有意义,我只是在玩):
#include<vector>
#include<iostream>
class Vec : public std::vector<int> {
public:
int operator[](int);
};
int Vec::operator[](int i) {
(*this)[i] = i;
std::cout << "OK";
return 123;
}
int main() {
Vec v;
v[0]=5;
}
不幸的是,我收到以下错误:
In member function ‘int Vec::operator[](int)’:
error: lvalue required as left operand of assignmen
In function ‘int main()’:
error: lvalue required as left operand of assignment
最佳答案
这个特殊错误是因为您没有返回左值
,通常定义为可以出现在赋值左侧的东西,例如v [0] = 5;
。正如其他答案中指出的那样,您有更多问题,但这是您遇到的错误消息 (a) 的具体问题。
重载索引运算符的正确规范是:
int& operator[] (const int nIndex);
如果您想将其视为左值
,则必须返回对该项目的引用(以便对其进行修改)。下面的代码显示了一个修复,尽管在这个简化的例子中显然所有数组索引都映射到相同的值:
#include <vector>
#include <iostream>
class Vec : public std::vector<int> {
public:
int& operator[] (int); // <-- note the '&'
private:
int xyzzy;
};
int& Vec::operator[] (int idx) { // <-- note the '&'
std::cout << "OK\n";
return xyzzy;
}
int main () {
Vec v;
v[0] = 5;
v[1] = 6;
std::cout << v[22] << '\n';
return 0;
}
这个的输出是:
OK
OK
OK
6
实际上,您不会将所有索引都映射到相同的值,上面的代码只是为了说明正确的函数签名。我懒得给出更完整的示例,因为使用非虚拟析构函数对类进行子类化通常会导致重要代码 (b) 出现问题。
(a) 通常认为将 std::vector
子类化不是一个好主意,因为析构函数不是虚拟的,因此在尝试时可能会遇到麻烦以多态方式销毁一个对象。
您最好使用has-a
关系(您的类包含 一个 vector )而不是is-a
关系(您继承的地方)。
不幸的是,这意味着您可能必须创建很多从您的类到底层 vector 的传递方法(尽管只有您需要的方法),但这将解决析构函数的问题。
(b) 参见(a) :-)
关于c++ - vector 和 []-运算符重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16660437/