重载向量下标运算符以获取char *或字符串

时间:2015-07-28 12:08:27

标签: c++ operator-overloading stdvector

我正在尝试重载下标运算符-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,谢谢。

我非常感谢您的帮助,但是您选择提供它。谢谢。

3 个答案:

答案 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具有对数复杂度。或者您可以考虑使用哈希表。