如何通过某个字段将对象插入到map结构中?
我有一个对象 - Employee,我想知道如何将该对象插入到按 char* lastName 字段排序的映射结构中。谢谢。 我的地图需要包含指向 Employee 对象而不是对象本身的指针。关键是员工的姓氏,地图需要按员工的姓氏排序,我应该使用multimap吗?
i have an object - Employee, and i want to know how to insert this object to a map structure sorted by char* lastName field. Thanx.
My map need to contain pointers to Employee objects not the objects themselves. the key is the last name of the employee, the map need to be sorted by the employees last name, should i use multimap?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
所以你有一个带有自定义比较器函数的 std::map (你已经重载了小于运算符)并且你想要插入对象以便它们处于正确的顺序?
其中
myKey
是地图的密钥。然而,从你的问题的声音来看,实际上听起来你正在使用该对象作为它自己的密钥。在这种情况下,只需使用 std::set,我还建议您不要使用 char* 作为存储姓氏的方法,而更喜欢使用 std::string。
编辑:
按照下面的注释,您是否必须能够将
const char*
传递到另一个函数中?如果是这样,仍然使用string
因为它有一个很好的方法.c_str()
专门用于旧版兼容性。它可以这样使用:瞧,你更安全了!
So you've got an std::map with a custom comparator function (you've overloaded the less than operator) and you want to insert objects so that they're in the right order?
where
myKey
is the key to your map. However, from the sound of your question it actually sounds like you're using the object as it's own key. In that case, just use std::set andI'd also suggest that you not use
char*
as a means to store lastName and prefer the std::string.EDIT:
Following the comments down below, are you having to be able to pass in a
const char*
into another function? If so, still usestring
as it has a nice method.c_str()
specifically for legacy compatibility. It can be used as so:and voila, you're much safer!
为
Employee
类定义bool 运算符 <(const Employee& other)
。或者,将 bool 运算符 <(const Employee& left, const Employee& right) 定义为非成员函数,并使其成为Employee< 的
friend
/代码>。第一种方法的优点是它是Employee
的本地方法,并且增强了封装性。后一种方法的优点是它适用于可转换为Employee
的任意两种类型。或者,您可以创建一个比较函子,而不是运算符 <()
,并将其传递给映射的构造函数。最后,使用
std::map
的insert()
成员函数插入新员工。std::map<>
还定义了operator []()
,它允许您插入到地图中。如果元素已存在于地图中,则insert()
函数不会插入该元素,而operator []()
如果元素已存在,则将更新该元素。Define
bool operator <(const Employee& other)
for theEmployee
class. Alternatively, definebool operator <(const Employee& left, const Employee& right)
as a non-member function, and make it afriend
ofEmployee
. The advantage of the first approach is that it's local toEmployee
, and that enhances encapsulation. The advantage of the latter approach is that it will work with any two types that are convertible toEmployee
. Alternatively, you can create a comparator functor, instead ofoperator <()
, and pass that the map's constructor.Lastly, use the
insert()
member function ofstd::map<>
to insert the new employees.std::map<>
also hasoperator []()
defined, and it allows you to insert into the map. Theinsert()
function will not insert the element if the element is already in the map, whereasoperator []()
will update the element if it already exists.您可以创建一个覆盖
operator()
的“函子”,引用两个对象并返回obj1
boolean 。 obj2
.例如:
当您创建 std::map 时,您可以将 EmployeeComparator 作为比较对象传递,如下所示:
其他发帖者重写
<
运算符的想法将起作用也是如此,但是使用这种方法,您可以选择一个标准来排序。按照我的方式,您可以拥有一个按姓氏排序的映射,另一个按员工 ID 排序的映射,等等。对于每个映射,您将传递一个不同的函子作为排序器。请记住,按照我的方式,如果您尝试按私有字段排序,请将您的排序函子声明为要排序的类的友元类。
You could create a "functor" which overrides
operator()
, taking references to two of your objects and returning a boolean ofobj1 < obj2
.For example:
When you create your std::map, you then pass
EmployeeComparator
as the comparison object, like so:Other posters' ideas of overriding the
<
operator will work too, but with that method you have pick a single criteria to sort by. With my way, you could have one map that sorts by last name, another that sorts by employee ID, etc. With each map you'd pass a different functor as your sorter.Keep in mind that with my way, if you are trying to sort by a private field, declare your sorting functor as a friend class of the class to be sorted.
正如 Philip Potter 在评论中所写,您应该明确使用
std::string
。因为在 cpp 代码中的多个位置/文件中声明的两个不同的char*
不会 具有相同的地址!由于 char* 只是一个整数,因此您将有多个 char* 键用于一个且只有一个相同的姓氏,这不是您想要的。走这条路:
As Philip Potter has written in comments, you should definetely use
std::string
. Because two differentchar*
declared at several places/files in your cpp code WON'T have the same addresses ! As a char* is nothing but an integer, you will have several char* keys for one and only one same lastname, and this is not what you want.go this way:
补充一下wheaties所说的,如果Employee对象包含它自己的键,您可能应该使用
set
。为了使用该集合,您必须为 Employee 对象显式定义比较方法。有两种方法可以做到这一点,要么定义operator<;对于对象:或者您可以定义一个函子,告诉集合用于比较:
编辑:要记住的一件非常重要的事情是
set
将其所有项目存储为常量。这样做是因为对
set
中的元素进行更改可能会更改元素的顺序,而set
无法检测到这一点并重新排序。如果您想要更新集合中包含的任何员工,这可能会出现问题。解决此问题的最佳方法是将您可能想要更改的 Employee 的任何数据成员声明为可变
。即使它们是const
,这也可以让您更改它们的值。Edit2:如果您决定继续使用地图并且键是
char *
,那么请记住,默认情况下地图将比较两个char *
它们的指针的值,而不是它们指向的字符串。在这种情况下,最好的办法是使用std::string
而不是 char *。或者,您可以定义一个函子来传递给映射:To add to what wheaties said, if the Employee object contains its own key, you should probably use a
set
. In order to use the set, you are going to have to explicitly define a method of comparison for the Employee object. There are two ways of doing that, either define operator< for the object:Or you can define a functor that you tell the set to use for comparison:
Edit: One VERY important thing to keep in mind is that a
set
stores all of it's items asconst
. It does this because it's possible that a change to an element in theset
could change the order of the elements andset
isn't capable of detecting this and reordering. This can be problematic if you want to update any of the employees contained in the set. The best way around this problem is to declare any of the data members of Employee that you might want to change asmutable
. This will let you change their values even when it'sconst
.Edit2: If you decide to continue using a map and the key is a
char *
, then keep in mind that by default the map is going to compare twochar *
s by the value of their pointer, not the string they point to. The best thing to do in this case is to usestd::string
instead of char *. Alternatively, you can define a functor to pass to the map: