重载向量下标运算符取一个 char * 或 string

Overload vector subscript operator to take a char * or string

我正在尝试重载下标运算符 - 我知道它是元素访问运算符 - 以获取 char * 或 std::string。

我有一个结构

struct foo
{
    int Age;
    const char *Name;
};

和一个 std::vector 将持有该结构的多个实例。

std::vector<foo>bar;

我的目标是能够通过调用名称来访问 bar 中的每个 foo。

std::cout<<"Simon's age is: "<<bar["simon"];

我一直在搜索 google 很长时间,试图找到一个示例或其他可以解决的问题,但没有成功。

我认为这会起作用

foo operator[](char *Name)
{
    for(int i=0;i<bar.size();i++)
    {
        if(bar[i].Name == Name){return bar[i];}
    }
}

然而显然我做错了什么

我知道这可以用 std::map 来完成,但我宁愿使用 std::vector,谢谢。

无论您选择提供何种帮助,我都将不胜感激。谢谢。

bar[i].Name == Name

可能是

strcmp(bar[i].Name, Name) == 0

但是,使用 std::strings 比管理普通字符指针更好。

而不是从向量中继承,而是创建一个 class 并将向量作为成员,并将你的 operator[] 放在 class 上。

做你想做的事需要从 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) 您正在使用 const char* 作为字符串类型,与 == 进行比较可能会失败,因为您比较的是两个指针而不是它们的内容。您需要使用 strcmp 或更好地使用 std::string(c++ 方式)

2) 如果您的索引运算符找不到您要查找的值怎么办?

我认为这不是一个正确的方法,但如果你真的想使用向量,你可以继承你自己的 class 并定义使用 const char* 作为索引参数的新运算符:

#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 容器继承(它们没有虚拟析构函数),但如果您不向继承的对象添加任何数据属性class,您应该没问题。

但我建议您考虑使用 std::map 作为容器,使用 std::string 作为索引/名称属性类型。搜索向量具有线性复杂度,但 std::map 具有对数复杂度。或者你可以考虑使用哈希表。