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