有时候我们想把用户自定义类型作为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的更多相关文章

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

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

  2. Freemaker如何遍历key为non-string类型的map?

    (一) 前置知识 Freemaker默认配置下会使用SimpleHash去包装后台传递的hashmap,下段摘抄自官方reference 同样,当你传递进去一个hashmap实例时,会替换为一个sim ...

  3. 一个关于自定义类型作为HashMap的key的问题

    在之前的项目需要用到以自定义类型作为HashMap的key,遇到一个问题:如果修改了已经存储在HashMap中的实例,会发生什么情况呢?用一段代码来试验: import java.util.HashM ...

  4. CXF2.7整合spring发布webservice,返回值类型是Map和List<Map>类型

    在昨天研究了发布CXF发布webservice之后想着将以前的项目发布webservice接口,可是怎么也发布不起来,服务启动失败,原来是自己的接口有返回值类型是Map. 研究了一番之后,发现: we ...

  5. STL map 按key值和按value值排序

    map是用来存放<key, value>键值对的数据结构,能够非常方便高速的依据key查到对应的value. 假如存储水果和其单位价格.我们用map来进行存储就是个不错的选择. 我们这样定 ...

  6. 结构体作为map的key或放入set中,需要重载<运算符

    结构体作为map的key或放入set中,需要重载<运算符,如下: typedef struct tagRoadKey{    int m_i32Type;    int m_i32Scale; ...

  7. map的key排序

    java map的key排序吗 java为数据结构中的映射定义了一个接口java.util.Map,他实现了四个类,分别是:HashMap,HashTable,LinkedHashMapTreeMap ...

  8. 理解ThreadLocal —— 一个map的key

    作用: 当工作于多线程中的对象使用ThreadLocal维护变量时,threadLocal为每个使用该变量的线程分配一个独立的变量副本. 接口方法: protected T initialValue( ...

  9. Java Map按键(Key)排序和按值(Value)排序

    Map排序的方式有很多种,两种比较常用的方式:按键排序(sort by key), 按值排序(sort by value).1.按键排序jdk内置的java.util包下的TreeMap<K,V ...

随机推荐

  1. C# 使用Vici WinService组件来创建Windows服务

    Vici WinService 是 Windows平台下使用C#开发的轻量级用于创建,删除服务的类库,您只需简单的几行代码即可实现多线程异步服务的创建,删除,运行 废话不多说,直接上代码 /***** ...

  2. [Functional Programming] mapReduce over Async operations with first success prediction (fromNode, alt, mapReduce, maybeToAsync)

    Let's say we are going to read some files, return the first file which pass the prediction method, t ...

  3. Android 色彩设计理念

    色彩 色彩从当代建筑.路标.人行横道以及运动场馆中获取灵感.由此引发出大胆的颜色表达激活了色彩,与单调乏味的周边环境形成鲜明的对照. 强调大胆的阴影和高光.引出意想不到且充满活力的颜色. 色样 – 0 ...

  4. PHPCMS增加投票选项代码

    <script src="jquery-1.10.1.js"></script> <tr> <th width="20%&quo ...

  5. ArcMap概化之消除真曲线

    在地理国情项目中,异常折线检查结果中,有报错为:几何类型为esriGeometryCircularArc不合法,而属性表中几何类型(Shape)内容为 "面",这是为何? 作为GI ...

  6. linux驱动杂项

    linux驱动 结构体中的逗号 http://zhouyang340.blog.163.com/blog/static/3024095920123495051607/ 下面我们看一个例子,Linux- ...

  7. OPENCV 常用函数

    1.cvCloneImage: IplImage* cvCloneImage( const IplImage* image ); 在使用函数之前,不用特地开辟内存,即该函数会自己开一段内存,然后复制好 ...

  8. Java从零开始学三十三四(JAVA IO-流简述)

    一.流概念(stream) File类并不能对文件内容进行读写. 读文件就是指:把文件的内中的数据读取到内存中来 写文件就是指:把内存中的数据写入到文件中去. 通过什么读写文件呢?文件流. 1.1.流 ...

  9. vb sendmessage 详解1

    SendMessage函数的常用消息及其应用(有点长,希望能对大家有所帮助)函数原型: Declare Function SendMessage Lib "user32" Alia ...

  10. java面试第九天

    图形界面: 布局管理器: CardLayout:卡片布局,面板重叠放置,只能看到一个,最先添加的会被显示出来,可以进行翻动 两种构造方法: CardLayout() 创建一个间隙大小为 0 的新卡片布 ...