1

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

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

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

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

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

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

谢谢

4

3 回答 3

1

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

Item 类的一些丑化换来的是极大的灵活性。发生丑化是因为 Item 必须从某个类派生,或者它必须声明一个特殊的成员变量来存储树链接。不过,这一切都包装得很好。

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

  • 为密钥重用 mName(与 std::set 不同)
  • 通过字符串查找Person(与 std::set 不同,无需构造 Person 进行查找)
于 2015-01-09T23:24:37.927 回答
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匹配他们的名字,例如。

于 2015-01-09T23:26:16.753 回答
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在任何实现迭代器的容器中进行搜索。

于 2015-01-09T23:26:41.897 回答