如何通过某个字段将对象插入到地图结构中?

时间:2010-09-02 13:50:48

标签: c++ stl insert

我有一个对象 - Employee,我想知道如何将此对象插入到按char * lastName字段排序的地图结构中。感谢名单。 我的地图需要包含指向Employee对象的指针而不是对象本身。关键是员工的姓氏,地图需要按员工的姓氏排序,我应该使用multimap吗?

5 个答案:

答案 0 :(得分:2)

所以你有一个带有自定义比较器函数的std :: map(你已经重载了less运算符)并且你想插入对象以使它们的顺序正确吗?

myMap.insert( make_pair( myKey, myEmployee ) );

其中myKey是地图的关键。但是,从您的问题的声音,它实际上听起来像你正在使用对象,因为它是自己的密钥。在这种情况下,只需使用std :: set和

mySet.insert( myEmployee );

我还建议您不要使用char*作为存储lastName的方法,而不是使用std :: string。

编辑:

按照下面的评论,你是否必须能够将const char*传递给另一个功能?如果是这样,仍然使用string,因为它有一个很好的方法.c_str()专门用于传统兼容性。它可以这样使用:

void stuffHappens(const char* _input){
    //magic happens in here
}

stuffHappens( myString.c_str() );

瞧,你更安全!

答案 1 :(得分:1)

bool operator <(const Employee& other)课程定义Employee。或者,将bool operator <(const Employee& left, const Employee& right)定义为非成员函数,并将其设为friend Employee。第一种方法的优点是它是Employee的本地,并且增强了封装。后一种方法的优点是它可以使用任何两种可转换为Employee的类型。或者,您可以创建比较器仿函数,而不是operator <(),并传递地图的构造函数。

最后,使用insert()的{​​{1}}成员函数插入新员工。 std::map<>也定义了std::map<>,并允许您插入地图。如果元素已经在地图中,operator []()函数将不会插入元素,而如果元素已经存在,insert()将更新元素。

答案 2 :(得分:1)

你可以创建一个覆盖operator()的“functor”,引用你的两个对象并返回obj1 < obj2的布尔值。

例如:

class EmployeeComparator
{
    public:
    bool operator()(const Employee& emp1, const Employee& emp2)
    {
        return strcmp(emp1.lastName, emp2.lastName) < 0;
    }
}

创建std :: map时,然后传递EmployeeComparator作为比较对象,如下所示:

std::map<Employee, T, EmployeeComparator> m;

其他海报覆盖<运算符的想法也会起作用,但使用该方法,您可以选择一个标准进行排序。按照我的方式,您可以使用一个按姓氏排序的地图,另一个按员工ID排序的地图等。对于每个地图,您将通过一个不同的仿函数作为您的分拣机。

请记住,按照我的方式,如果您尝试按私有字段排序,请将排序仿函数声明为要排序的类的朋友类。

答案 3 :(得分:1)

要添加到wheaties所说的内容,如果Employee对象包含自己的密钥,则应该使用set。为了使用该集,您将必须显式定义Employee对象的比较方法。有两种方法可以做到这一点,或者定义运算符&lt;对象:

class Employee
{
public:
  bool operator<(const Employee &rhs)
  {
    return strcmp(lastName, rhs.lastName) < 0;
  }
...
};

或者您可以定义一个函子,告诉该集用于比较:

struct EmployeeLessThan
{
  bool operator()(const Employee &lhs, const Employee &rhs)
  {
    return strcmp(lhs.lastName, rhs.lastName) < 0;
  }
};

std::set<Employee, EmployeeLessThan> myEmployees;

编辑:要记住的一件非常重要的事情是set将所有项目存储为const。这样做是因为set中元素的更改可能会改变元素的顺序,set无法检测到这种情况并重新排序。如果要更新集合中包含的任何员工,则可能会出现问题。解决此问题的最佳方法是将您可能希望更改为mutable的任何Employee数据成员声明。即使它是const,也可以让您更改其值。

Edit2:如果你决定继续使用地图并且密钥是char *,那么请记住,默认情况下,地图会将两个char * s与其指针的值进行比较,而不是他们指向的字符串。在这种情况下,最好的办法是使用std::string而不是char *。或者,您可以定义一个传递给地图的仿函数:

struct CharStarLessThan
{
  bool operator()(const char *lhs, const char *rhs)
  {
    return strcmp(lhs, rhs) < 0;
  }
};

std::map<char *, Employee, CharStarLessThan> myEmployees;

答案 4 :(得分:1)

正如菲利普波特在评论中写的那样,你应该定义使用std::string。因为在您的cpp代码中的多个地方/文件中声明了两个不同的char* 不会具有相同的地址!由于char *只是一个整数,因此只有一个char *键只有一个且只有一个相同的姓氏,这不是你想要的。

走这条路:

std::map<std::string,YourType> yourMap;
std::string strMyLastName = "Rolland";
YourType aValue;
yourMap[strMyLastName ] = aValue;