【问题标题】:How to refer to an class element in map::find() function?如何在 map::find() 函数中引用类元素?
【发布时间】:2018-02-27 11:26:15
【问题描述】:

我想用地图创建一个简单的数据存储,

map<int , Person> people;

人在哪里

class Person
{
    string name;
    int age;
public:
    Person() : name("noname"), age(0) {}
    Person(string name, int age) : name(name), age(age) {}

    void print()
    {
        cout << "| " << name << " | " << age << endl;
    }
};

我在 map::find() 函数中引用 people.name 时遇到问题。可能我只是不知道正确的语法,我找不到答案。它可能看起来应该是这样的,但 namePerson 类的元素,所以我想它应该会给我一个错误。

if (people.find(name) != people.end())
    {
        people.erase(name);
        cout << name << " removed from data base" << endl;
    }
else
    {
        cout << name << " not found" << endl;
    }

抱歉我的无知,但我最近才开始编程,这就是为什么我不知道基本语法并且有时会感到困惑。

【问题讨论】:

  • 请提供minimal reproducible example。例如,您从哪里拨打find?你有错误吗?如果是这样,请将其复制粘贴到问题中。您是否期望一个,但没有得到它,请解释为什么您期望它是一个错误。
  • 请查看此C++ books 列表。
  • std::map 可能不是您要查找的数据结构。
  • 你有没有想过如果你有多个同名的人会发生什么?
  • @KillzoneKid 感谢您指出这一点。我想将键值与特定人的某个 id 号连接起来,在这种情况下 erase 条件必须确保要删除哪个人。

标签: c++ oop stl


【解决方案1】:

您的问题是您的地图设计错误。如果你想使用一个名字来查找一个人,那么这个名字必须是地图的键,即

map<string, Person>

其中字符串是名称。

【讨论】:

  • 我想使用 int 键值来为一个人分配一个 id。我创建了这样的人:people[0] = Person("Mike", 40);,并且在某些时候我想通过找到一个名字来用map::erase 删除这个人。是否可以保留 int 键类型,并且仍然寻找名称?
  • @Zezwul 您可以遍历地图中的所有条目,直到找到要删除的条目(但请注意,您的设计中没有任何内容可以使名称唯一)。或者,您需要更复杂的数据结构。从名称到 ID 的第二张地图怎么样?使用名称查找 ID,然后查找要从第一张地图中删除的 ID。
  • 我想我还是错过了一些东西。我认为 ID(键值)可以使名称个性化,因为来自 peoplePerson 类实例)的每个人都分配了其唯一的 int 值。
  • people[0] = Person("Mike", 40); people[1] = Person("Mike", 40);。 ID不同但名称相同?也许我们在谈论不同的事情。
  • 我想将键值与特定人的某个 ID 号连接起来,在这种情况下 erase 条件必须确定要删除的人,所以当有涉及两个或多个相同名称的冲突,ID 将是决定哪个是必不可少的。就像我说的,我是初学者,所以有时我很困惑。
【解决方案2】:

如果您想要一个带有相应对象的name 字典,您是否想要一个std::map&lt;string, Person&gt;

在这种情况下你可以这样做:

auto person = nameToPersonDictionary.find(personName); 
if (person != nameToPersonDictionary.end()){
    nameToPersonDictionary.erase(personName);
    // person is a reference to object Person 
}else{ // Not found
}

如果您只想构建一个查找表,您可以考虑std::set。另一个用例,如果name 是对象Person 的不可变属性(即name 永远不会为一个人修改)set 更适合。

您必须提供 &lt; 运算符的重载才能使 set 工作。

提供重载的一个简单示例是:

// This assumes that there are can't be two distinct person with same name
bool operator<(const Person &left, const Person &right){
    return left.name < right.name;  
}

然后可以直接使用Person对象的实例进行查询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    • 1970-01-01
    • 2017-08-16
    • 1970-01-01
    相关资源
    最近更新 更多