zoukankan      html  css  js  c++  java
  • 如何在STL的map中使用结构体作为键值

      这里首先给出容器map的原型:

    template <
    	class Key,
    	class T, 
    	class Compare = less<Key>,
    	class Alloc = alloc>
    class map{
    	...
    }
    

      可以看到模板参数一共有四个,第一个就是Key,即键;第二个就是值;第四个就是空间配置器,默认使用alloc(随STL版本不同而不同)。那么第三个是啥?

      我们知道,map的底层数据结构,其实是树,更确切的说,是一个RB-tree(红黑树)。RB-tree树在进行插入时,会按照一定的规则把新元素插入特定位置。相应的,进行删除操作时,也会按一定规则修改树的结构。此外,树形结构也是高效率查询的基本保证。但是,插入、删除、查询时都要依赖与节点之间的比较,对于map来说,我们必须提供对Key进行比较的函数或操作符。这也就是第三个模板参数的意义。

      默认情况下,第三个模板参数使用less<Key>类型,其中less<T>是一个仿函数。下面给出less的定义:

    template<class _Ty>
    	struct less
    		: public binary_function<_Ty, _Ty, bool>
    	{	// functor for operator<
    	bool operator()(const _Ty& _Left, const _Ty& _Right) const
    		{	// apply operator< to operands
    		return (_Left < _Right);
    		}
    	};
    

      如果创建一个less类的对象less_obj,然后使用less_obj(A,B)这样的写法,就相当于调用了less的operator()方法。而最终执行时,会自动获取A与B的类型,并使用此类型的operator<来实现less类的operator()方法。到现在为止,就理清了map中的第三个模板参数的所有问题。

      接下来的问题就是,如何在map中使用一个结构体作为Key。举例来说,现在有一个结构体:

    typedef struct _info_head{
    	u_int src_ip;
    	u_int dest_ip;
    	u_int src_port; 
    	u_int dest_port;
    }info_head;
    

      如果直接使用info_head这个结构体来填入map中的第一个模板参数的位置,并且不指定第三个模板参数的话,那么就会使用less<info_head>作为map中对键值进行比较的操作符。而通过上述分析,在less<info_head>中最终使用的,是info_head类型的operator<操作符。那么显然的,只给出上边的简单的对结构体的定义,是不够的。因此,要想使用结构体来作为map中的Key,那就必须为此结构体重载并实现operator<操作符。如果没能做到这一点,就会在编译时报错,因为编译器找不到对应的operator<。其中,VS2010下的编译错误代码是:error C2784。

      修改后的结构体代码如下:

    typedef struct _info_head{
    	u_int src_ip;
    	u_int dest_ip;
    	u_int src_port; 
    	u_int dest_port;
    
    	bool operator<(const struct _info_head & other) const {
    	//Must be overloaded as public if this struct is being used as the KEY in map.
    		if (this->src_ip < other.src_ip) return true;
    		if (this->dest_ip < other.dest_ip) return true;
    		if (this->src_port < other.src_port) return true;
    		if (this->dest_port < other.dest_port) return true;
    		return false;
    	}
    }info_head;
    

      不过这并不是唯一的办法。另外一种方式,就是自己写一个仿函数,实现对info_head类型的比较。然后在info_head作为map中第一个模板参数的时候,填入这个仿函数作为map的第三个模板参数。不过这样做显然不如上边这种办法简单,这里也不具体叙述了。

  • 相关阅读:
    【bzoj1499】[NOI2005]瑰丽华尔兹 【单调队列优化dp】
    【poj3709】K-Anonymous Sequence 【斜率优化dp】
    【bzoj4566】[Haoi2016]找相同字符【后缀自动机】
    【Play】蜂鸣器音乐 校歌
    【poj2373】Dividing the Path【单调队列优化dp】
    【bzoj2010】SubString【后缀自动机+LCT】
    【bzoj1047】[HA蛤OI2007]理想的正方形【单调队列】
    【poj1743】Musical Theme【后缀数组】
    【bzoj4293】[PA2015]Siano【线段树】
    【bzoj4553】[Tjoi2016&Heoi2016]序列【树套树 树状数组套平衡树】
  • 原文地址:https://www.cnblogs.com/superpig0501/p/4098310.html
Copyright © 2011-2022 走看看