我正在尝试重载下标运算符-i知道它作为元素访问运算符 - 采用char *或std :: string。
我有一个结构
struct foo
{
int Age;
const char *Name;
};
和一个将持有此结构的多个实例的std :: vector。
std::vector<foo>bar;
我的目标是能够通过按名称调用每个foo来访问它们。
std::cout<<"Simon's age is: "<<bar["simon"];
我一直在搜索谷歌很长一段时间,试图寻找一个例子或其他东西,没有运气。
我认为这会起作用
foo operator[](char *Name)
{
for(int i=0;i<bar.size();i++)
{
if(bar[i].Name == Name){return bar[i];}
}
}
然而,显然我做错了
我知道这可以用std :: map完成,但我宁愿使用std :: vector,谢谢。
我非常感谢您的帮助,但是您选择提供它。谢谢。
答案 0 :(得分:3)
要做你想做的事情,需要从std :: vector继承。否则你不能重载它的方法。
类似以下内容(未经测试)。
struct fooVector : public std::vector<foo> {
typedef std::vector<foo> super;
using super::size;
...
foo& operator[](char const* Name) {
super& self=*this;
for(int i=0;i<size();i++)
{
if( ! strcmp( self[i].Name, Name) ){return self[i];}
}
// Need to do something reasonable if not found
}
};
答案 1 :(得分:1)
bar[i].Name == Name
可能意味着
strcmp(bar[i].Name, Name) == 0
但是,使用std::string
比使用普通的char指针更好。
而不是继承形式的向量,而是创建一个以向量作为成员的类,并在该类上使用operator[]
。
答案 2 :(得分:0)
首先,您的测试存在一些问题:
1)你使用const char *作为字符串类型,与==比较可能会因为你比较两个指针而不是它们的内容而失败。你需要使用strcmp或更好地使用std :: string(c ++方式)
2)如果您的索引操作员找不到您要查找的值,该怎么办?
我不认为这是一种正确的方法,但是如果你真的想使用vector,你可以继承你自己的类并定义使用const char *作为索引参数的new运算符:
#include <vector>
#include <iostream>
#include <string.h>
struct foo {
int age;
const char *name;
};
class MyVector : public std::vector<foo> {
public:
const foo* operator[](const char* name) const {
for (auto it=cbegin(); it != cend(); ++it) {
if (strcmp(it->name, name) == 0) {
return &(*it);
}
}
return nullptr;
}
};
int main(int argc, char *argv[]) {
foo foo1 = { 10, "abc" };
foo foo2 = { 20, "test" };
MyVector v;
v.push_back(foo1);
v.push_back(foo2);
std::cout << "test: " << v["test"]->age << std::endl;
}
虽然通常不建议从stl容器继承它们(它们没有虚拟析构函数),但是如果你不为继承的类添加任何数据属性,你应该没问题。
但我建议你考虑使用std :: map作为容器,使用std :: string作为索引/名称属性类型。搜索向量具有线性复杂度,但std :: map具有对数复杂度。或者您可以考虑使用哈希表。