在std :: set上按名称查找对象

时间:2015-01-09 23:13:58

标签: c++ stdset

我需要在std:set(或任何其他类型的查找表)中存储一些对象,并按名称搜索它们。

例如,假设我有一个类(伪代码):

class Person
{
    std::string mName;
    int mAge;
    ... //etc
};

我想将其存储在容器中并按名称搜索对象。我不能在std :: set上插入它们,因为据我所知,我必须构造一个完整的对象进行搜索。

我的第二个是使用像std :: map这样的std :: map,但是,我需要复制这个名称,我不想复制密钥。

有没有办法将这种对象存储在std :: set(或任何其他容器)中并通过键(而不是对象)进行搜索?

谢谢

3 个答案:

答案 0 :(得分:1)

请查看boost :: intrusive容器,特别是boost::intrusive::set

作为对Item类的一些改进的交换,具有很大的灵活性。由于Item必须派生自某个类,或者它必须声明一个特殊的成员变量来存储树链接,因此发生了丑化。尽管如此,这一切都很好。

关于特定请求,boost :: intrusive :: set允许

  • 重用mName作为密钥(与std :: set不同)
  • lookup字符串的人(与std :: set不同,不需要构造Person来进行查找)

答案 1 :(得分:0)

您可以使用std::find_if,例如,如果您有std::set<Person> people

auto match = std::find_if(people.begin(), people.end(), [](const Person& foo){return foo.mName == "Bob";});
if (match != people.end())
{
    std::cout << "Found Bob!"
}

因此,您不需要创建完整的Person对象,只需std::string来匹配其名称。

答案 2 :(得分:0)

所以你可以使用find_if来实现这个目标:

struct find_by_name {
    find_by_name(const std::string & name) : name(name) {}
    bool operator()(const Person & person) {
        return person.name == name;
    }
private:
    std::string name;
};

// in your code

std::set<Person>::iterator result = std::find_if(people.begin(), people.end(), 
                                              find_by_name("Ben"));
if(result != people.end()) {
    // we found something
}
else {
    // no match
}

这种方式只基于生成的字符串(在结构中)进行搜索,并且它具有很强的适应性,您可以使用任何字符串对其进行初始化,您也可以使用它在任何实现的字符串中搜索person迭代器。