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的第三个模板参数。不过这样做显然不如上边这种办法简单,这里也不具体叙述了。

  • 相关阅读:
    UVa 1451 Average (斜率优化)
    POJ 1160 Post Office (四边形不等式优化DP)
    HDU 3507 Print Article (斜率DP)
    LightOJ 1427 Substring Frequency (II) (AC自动机)
    UVa 10245 The Closest Pair Problem (分治)
    POJ 1741 Tree (树分治)
    HDU 3487 Play with Chain (Splay)
    POJ 2828 Buy Tickets (线段树)
    HDU 3723 Delta Wave (高精度+calelan数)
    UVa 1625 Color Length (DP)
  • 原文地址:https://www.cnblogs.com/superpig0501/p/4098310.html
Copyright © 2011-2022 走看看