使用用户自定义类型作为map的key
有时候我们想把用户自定义类型作为std::map的键值。
方法一)最简单的方法就是实现该自定义类型的<操作符,代码如下:
class Foo
{
public:
Foo(int num_)
: num(num_)
{
}
bool operator < (const Foo & cmp) const
{
return num < cmp.num;
}
int num;
};
之后就可以使用Foo作为map的key了:
map<Foo, int> dict; // 该句等同于map<Foo, int, std::less<Foo> > dict;
dict[Foo(1)] = 1;
不过有时候,这招不好使,比如对下面的Foo2:
typedef std::pair<Foo, int> Foo2;
方法二)定义一个比较操作符,使用它作为map的模板参数,代码如下:
class Foo2Comparator
{
public:
bool operator()(const Foo2& key1, const Foo2& key2) const
{
if (key1.first < key2.first)
{
return true;
}
else if (key2.first < key1.first)
{
return false;
}
else
{
return key1.second < key2.second;
}
}
};
这时候可以使用Foo2作为map的key了:
map<Foo2, int, Foo2Comparator> dict2;
dict2[Foo2(Foo(1), 100)] = 1;
方法三)为用户自定义类型特化std::less,代码如下:
namespace std
{
template <>
struct less<Foo2>
: public binary_function <Foo2, Foo2, bool>
{
bool operator()(const Foo2& key1, const Foo2& key2) const
{
if (key1.first < key2.first)
{
return true;
}
else if (key2.first < key1.first)
{
return false;
}
else
{
return key1.second < key2.second;
}
}
};
}
使用这种方法,声明map时无需指定比较函数对象,因为默认的比较对象就是std::less<T>,
map<Foo2, int> dict2;
dict2[Foo2(Foo(1), 100)] = 3;
======================================================
三种方法里面我最喜欢第二种,虽然使用起来略微复杂(多了一个模板参数),但最为明确清晰。
另外如果使用std::pair<T1, T2>作为map的key,若T1、T2是原始类型,那么使用默认的std::less<std::pair<T1, T2> >一般就ok了,没啥必要去自己折腾。
typedef std::pair<double, int> Pos;
std::map<Pos, int> dict3;
dict3[Pos(1.1, 10)] = 100;
使用用户自定义类型作为map的key的更多相关文章
- 关于set或map的key使用自定义类型的问题
我们都知道set或map的key使用自定义类型时必须重载<关系运算符 但是,还有一个条件,所调用重载的小于操作符,使用的对象必须是const 而对象调用的方法也必须是const的 1 #incl ...
- Freemaker如何遍历key为non-string类型的map?
(一) 前置知识 Freemaker默认配置下会使用SimpleHash去包装后台传递的hashmap,下段摘抄自官方reference 同样,当你传递进去一个hashmap实例时,会替换为一个sim ...
- 一个关于自定义类型作为HashMap的key的问题
在之前的项目需要用到以自定义类型作为HashMap的key,遇到一个问题:如果修改了已经存储在HashMap中的实例,会发生什么情况呢?用一段代码来试验: import java.util.HashM ...
- CXF2.7整合spring发布webservice,返回值类型是Map和List<Map>类型
在昨天研究了发布CXF发布webservice之后想着将以前的项目发布webservice接口,可是怎么也发布不起来,服务启动失败,原来是自己的接口有返回值类型是Map. 研究了一番之后,发现: we ...
- STL map 按key值和按value值排序
map是用来存放<key, value>键值对的数据结构,能够非常方便高速的依据key查到对应的value. 假如存储水果和其单位价格.我们用map来进行存储就是个不错的选择. 我们这样定 ...
- 结构体作为map的key或放入set中,需要重载<运算符
结构体作为map的key或放入set中,需要重载<运算符,如下: typedef struct tagRoadKey{ int m_i32Type; int m_i32Scale; ...
- map的key排序
java map的key排序吗 java为数据结构中的映射定义了一个接口java.util.Map,他实现了四个类,分别是:HashMap,HashTable,LinkedHashMapTreeMap ...
- 理解ThreadLocal —— 一个map的key
作用: 当工作于多线程中的对象使用ThreadLocal维护变量时,threadLocal为每个使用该变量的线程分配一个独立的变量副本. 接口方法: protected T initialValue( ...
- Java Map按键(Key)排序和按值(Value)排序
Map排序的方式有很多种,两种比较常用的方式:按键排序(sort by key), 按值排序(sort by value).1.按键排序jdk内置的java.util包下的TreeMap<K,V ...
随机推荐
- 在C#中使用属性控制 XML 序列化来解析XML
今天需要解析一个XML,这个XML和一般情况用.NET的序列化出来的格式不太一样. 我就又补习了一下. 分享一下学习成果吧. 示例代码下载: http://download.csdn.net/deta ...
- Sql Server-查询一列的数据进行拼接
select convert(VARCHAR(10),memberid) +',' from t_member where teamid = 1009 for xml path('')
- 关于COM的Unicode string的精彩论述
I need to make a detour for a few moments, and discuss how to handle strings in COM code. If you are ...
- (算法)Trapping Rain Water I
题目: Given n non-negative integers representing an elevation map where the width of each bar is 1, co ...
- TotalCommander如何比较文件夹并提取出重复的文件
1 如图所示,我左侧有一万本多小说,右侧有两千五百多本小说,我希望比较这两个文件夹相同的小说并剪切到一个新的文件夹中. 2 我们使用Total Commander对比这两个文件夹 3 随后两个文件夹相 ...
- Android 之 AndroidManifest.xml 详解(二)
[10]<activity> Activity活动组件(即界面控制器组件)的声明标签,Android应用中的每一个Activity都必须在AndroidManifest.xml配置文件中声 ...
- htmlayout做的虎鲸宝宝
昨天在auto论坛上偶遇一哥们作的虎鲸宝宝例子,尽管作者提供了auto的源码… … 一个C++老农的悲哀.不过大概看了下流程,最后想想:选什么样的语言已经不重要了. 最重要的是里边的资源文件可以拿来耍 ...
- Java从零开始学二十(集合简介)
一.为什么需要集合框架 数组的长度是固定的,但是如果写程序时并不知道程序运行时会需要多少对象.或者需要更复杂的方式存储对象,---那么,可以使用JAVA集合框架,来解决这类问题 二.集合框架主要接口 ...
- Python3.2官方文档翻译--标准库概览(一)
7.1 操作系统接口 Os模块提供主要很多与操作系统交互的函数. >>> import os >>> os.getcwd() # Return the curren ...
- html5之canvas画图 1.写字板功能
写字板事例: 写字板分析:1.点击鼠标開始写字(onmosedown)2.按下鼠标写字(onmousemove)3.松开鼠标,停下写字(撤销onmousemove事件): 代 ...