若干问题:

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. Java中break和continue跳出指定循环

    https://www.cnblogs.com/miys/p/b7f6a463bc58785d74a8a7fccd1f1243.html 在Java中,break和continue可以跳出指定循环,在 ...

  2. ios-邮箱正则表达式判断

    - (void)loadData { NSMutableArray *array = [NSMutableArray arrayWithCapacity:10]; if ([self.title is ...

  3. day 05JVM和深入理解java虚拟机

    -----------------Java 虚拟机发展史 PS: Sun公司有 HotSpot, BEA公司有JRockit,IBM有 J9  这三个是高性能VM 在Oracle收购Sun和BEA这两 ...

  4. react 简书开发笔记

    详见文章<React简书开发实战课程笔记>

  5. redis服务以及phpredis扩展的安装

    一.下载软件包 下载redis wget http://download.redis.io/releases/redis-3.0.7.tar.gz 下载redis的php扩展 wget http:// ...

  6. KMPlayer速度步进设置及快捷键设置和同级视频自动加入播放列表

    速度步进设置 快捷键设置  同级视频自动加入播放列表

  7. 理解Lambda表达式和闭包

    了解由函数指针到Lambda表达式的演化过程 Lambda表达式的这种简洁的语法并不是什么古老的秘法,因为它并不难以理解(难以理解的代码只有一个目的,那就是吓唬程序员) #include " ...

  8. Oracle12C版本安装步骤

    一.下载路径 http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html file1,file ...

  9. create a simple COM object

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAArsAAAGYCAIAAADN0b3QAAAgAElEQVR4nO29749c1b2nW/4Lzh8wUr

  10. asterisk todo

    1, 如何让用户打一个密码才能继续外拨? 可以利用__9xxx那种做法 2,如何和onsip连起来? 3, 如何记录所有拨打记录?