若干问题:

struct Node {
int k, b;
friend bool operator <(Node a, Node b) {
return a.k < b.k;
}
}node1, node2; map<Node, int> mp; int main() { node1.k = ;
node1.b = ;
mp[node1] = ;
node1.k = ;
node1.b = ;
printf("%d\n", mp.count(node1));
//输出1
return ;
}
struct Node {
int k, b;
friend bool operator <(Node a, Node b) {
if (a.k != b.k) return a.k < b.k;
else return a.b < b.b;
}
}node1, node2; map<Node, int> mp; int main() { node1.k = ;
node1.b = ;
mp[node1] = ;
node1.k = ;
node1.b = ;
printf("%d\n", mp.count(node1));
//输出0
return ;
}

1、以结构体为Key

map内部自建一颗红黑树(一种非严格意义上的平衡二叉树),红黑树具有对数据自动排序(默认是以less<>升序对元素排序(排序准则也可以修改))的功能,因此在map内部所有的关键字都是有序的。当key为基本数据类型时,不存在问题。但是当关键字是一个结构体时,涉及到排序就会出现问题,因为它没有小于号操作,insert等函数在编译的时候就会出错,下面给出解决这个问题的方法:

对操作符"<"进行重载(不可以重载大于号)

#include <map>
#include <iostream>
#include <string>
using namespace std;
struct Node{
int id;
string name;
friend bool operator < (Node a,Node b)
{
//指定排序策略,按id排序,如果id相等的话,按name排序
if (a.id != b.id) return a.id > b.id;
else return a.name > b.name;
}
}StudentInfo, *pStudentInfo; //学生信息 int main(){
int nSize;
//用学生信息映射分数
map<Node, int> mapStudent;
map<Node, int>::iterator it; StudentInfo.id = ;
StudentInfo.name = "student_one";
mapStudent.insert(pair<Node, int>(StudentInfo, ));
StudentInfo.id = ;
StudentInfo.name = "student_two";
mapStudent.insert(pair<Node, int>(StudentInfo, )); for (it = mapStudent.begin(); it != mapStudent.end(); it++)
cout << it->first.id << " " << it->first.name << " " << it->second << endl; }
printf("%d",mp.find(StudentInfo)->second);
printf("%d",mp[StudentInfo]);  都可以

重载的部分可以写到结构体外,但有三点要求:

1、把friend去掉,把小于号改成一对小括号。

2、用struct把函数包装起来。

3、map的定义方式改为map<Node, int, cmp> mapStudent;

如:

#include <map>
#include <iostream>
#include <string>
using namespace std;
struct Node{
int id;
string name; }StudentInfo, *pStudentInfo; //学生信息 struct cmp {
bool operator () (Node a, Node b)
{
//指定排序策略,按nID排序,如果nID相等的话,按strName排序
if (a.id != b.id) return a.id > b.id;
else return a.name > b.name;
}
};
map<Node, int, cmp> mapStudent;
map<Node, int, cmp>::iterator it;
int main(){
int nSize;
//用学生信息映射分数 StudentInfo.id = ;
StudentInfo.name = "student_one";
mapStudent.insert(pair<Node, int>(StudentInfo, ));
StudentInfo.id = ;
StudentInfo.name = "student_two";
mapStudent.insert(pair<Node, int>(StudentInfo, )); for (it = mapStudent.begin(); it != mapStudent.end(); it++)
cout << it->first.id << " " << it->first.name << " " << it->second << endl; }
printf("%d",mp.find(StudentInfo)->second);
printf("%d",mp[StudentInfo]); 也可以

2、以结构体指针为Key,可以不重载<号,因为地址可以比较大小。

但是也可以根据指针指向的内容重载小于号,但此时重载函数必须放在自定义的结构体外面。(原因不详。。。)

#include <map>
#include <iostream>
#include <cstdio>
using namespace std; struct Key
{
int x,y;
}*ptr; struct CompareKey
{
bool operator()(Key *in_a, Key *in_b)
{
return in_a->x < in_b->x;
}
}; map<Key *, int, CompareKey> mp; int main()
{ for (int i = ; i < ; i++)
{
Key *k = new Key;
if(i==) ptr=k; k->x = i;
k->y = i+; mp.insert(make_pair(k, i));
} map<Key *, int, CompareKey>::iterator it;
for(it=mp.begin();it!=mp.end();it++){
if(it->first==ptr){
printf("%d %d %d\n",it->first->x,it->first->y,it->second);
}
} }

2、以自定义struct或struct指针作为map的Key的更多相关文章

  1. 指针做MAP的KEY的TEST

    用struct做map的key会需要"operator <"等等,还会出现奇怪的问题可能. 试了下用指针做key,看看效果: #include <iostream> ...

  2. typedef&nbsp;struct与struct的区别

    typedef struct与struct的区别 1. 基本解释 typedef为C语言的关键字,作用是为一种数据类型定义一个新名字.这里的数据类型包括内部数据类型(int,char等)和自定义的数据 ...

  3. 结构体struct sockaddr_in, struct sockaddr,struct in_addr

    一.结构体 struct sockaddr_in,  struct sockaddr,  struct in_addr struct sockaddr_in,  struct sockaddr,str ...

  4. typedef struct与struct定义结构体

    今天在定义结构体的时候发现typedef struct与struct定义结构体有一些不同之处: 结构也是一种数据类型, 能够使用结构变量, 因此,  象其他 类型的变量一样, 在使用结构变量时要先对其 ...

  5. linux网络接口,struct ifreq struct ifconf结构

    网络相关的ioctl请求的request参数及arg地址必须指向的数据类型如下表所示: 接口 SIOCGIFCONF SIOCSIFADDR SIOCGIFADDR SIOCSIFBRDADDR SI ...

  6. map的key 为指针

    STL中map的key能否用char *呢?当然可以! 在程序中需要用到一个map,本来是这样写的,map<string, int> mapStr; 为了追求效率,把string改成了ch ...

  7. 关于set或map的key使用自定义类型的问题

    我们都知道set或map的key使用自定义类型时必须重载<关系运算符 但是,还有一个条件,所调用重载的小于操作符,使用的对象必须是const 而对象调用的方法也必须是const的 1 #incl ...

  8. [C++学习笔记14]动态创建对象(定义静态方法实现在map查找具体类名对应的创建函数,并返回函数指针,map真是一个万能类)good

    [C++学习笔记14]动态创建对象   C#/Java中的反射机制 动态获取类型信息(方法与属性) 动态创建对象 动态调用对象的方法 动态操作对象的属性 前提:需要给每个类添加元数据 动态创建对象 实 ...

  9. Flink 自定义source和sink,获取kafka的key,输出指定key

    --------20190905更新------- 沙雕了,可以用  JSONKeyValueDeserializationSchema,接收ObjectNode的数据,如果有key,会放在Objec ...

随机推荐

  1. Linux 服务器配置、运行、不用敲命令(新手必备!) - 宝塔全攻略建站一条龙

    Linux 服务器配置.运行.不用敲命令 WordPress 建站攻略 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整 ...

  2. ElasticSearch 从零到入门

    摘自:https://www.cnblogs.com/keme/p/10108918.html

  3. com.sun.org.apache.xerces.internal.impl.dv.util.Base64出现的问题

    import com.sun.org.apache.xerces.internal.impl.dv.util.Base64; 出现的问题是这个在eclipse中无法使用,解决方法如下: (1)进入ec ...

  4. Python——dict(自定义类作key)

    Python的dict要求key为不可变数据类型,通常采用str或int,但在某些应用场景下,需要采用自定义类型对象作key, 此时的自定义类需要实现两个特殊方法:__hash__.__eq__,用于 ...

  5. Fedora初体验

    ========1. 下载https://getfedora.org/zh_CN/workstation/download/下载如下2个文件:Fedora-Workstation-Live-x86_6 ...

  6. 浅谈STM32L071硬件I2C挂死

    STM32的IIC问题一直存在,在网上也被很多人吐槽,然而FAE告诉我,硬件IIC的问题在F1,F3,F4系列单片机存在,而在L0上已经解决了,然而这几天调试加密芯片和显示芯片,都是IIC芯片,却再一 ...

  7. stl本子

    记事本,不要想到奇怪的地方去 迭代器什么的不会玩quq set: #include<set> set<int> quq; quq.insert(qvq); -- 插入 quq. ...

  8. Spring boot Mybatis 整合

    PS: 参考博客 PS: spring boot配置mybatis和事务管理 PS: Spring boot Mybatis 整合(完整版)   这篇博客里用到了怎样 生成 mybatis 插件来写程 ...

  9. RESTful Web API 理解

    REST 是一种应用架构风格,不是一种标准,是面向资源架构(ROA)风格,与具体技术平台无关,REST架构的应用未必建立在Web之上,与之对应的是传统的Web Service 采用的面向操作的RPC架 ...

  10. HappytimeOnvif Client V8.3的使用

    1.system-->system settings-->勾选RTP RTSP 2.start video poll