map中key为结构体的用法

最近在使用stl中的map容器时,碰到key为结构体的情况,总结如下,以便提醒自己。
我的使用情景是,我需要根据不同的比例尺、道路类型这两个参数获取到对应的道路宽度,由于我是使用map解决这个问题的,
自然而然的就以比例尺、道路类型这两个参数为key,道路宽度为value,建立的key如下:

  typedef  struct  tagRoadKey 
  {
      int  nType;
      int  nScale;
      }
  }ROADKEY;

但是编译的时候,报了这个错误
d:\program files\microsoft visual studio\vc98\include\functional(86) : error C2784: 'bool __cdecl std::operator <(const class std::multimap<_K,_Ty,_Pr,_A> &,const class std::multimap<_K,_Ty,_Pr,_A> &)' : could not deduce template argument for 'const
 class std::multimap<_K,_Ty,_Pr,_A> &' from 'const struct tagRoadKey'

说实话,当初不太明白这是什么错误,但从个人经验来判断,问题肯定出在这个key上面,后来google下,看到了别人写的文章,才知道原因,原来map中的key默认是以less<>升序对元素排序(排序准则也可以修改),也就是说key必须具备operator<对元素排序,而平常我们的用的基本上都是基本类型元素作为key,所以就不存在这个问题了,更详细的解释请看C++标准程序库一书,第六章,set容器章节。
改正后的结构体如下:

typedef  struct  tagRoadKey 
{
    int  nType;
    int  nScale;

    bool   operator   < ( const  tagRoadKey &  other)  const
    {
        if  (nType  <  other.nType)         // 类型按升序排序
        {
            return   true ;
        }
        else   if  (nType  ==  other.nType)   // 如果类型相同,按比例尺升序排序
        {
            return  nScale  <  other.nScale;
        }
       
        return   false ;
    }
}ROADKEY;


完整代码如下:

  ///////// /.h ////// /
  #ifndef _CROADWIDTHMNG_H_
  #define  _CROADWIDTHMNG_H_
  #include  < map >
 
  using   namespace  std;
 
  /*
  说明:根据当前比例尺、道路类型获取对应的道路宽度
  */
  typedef  struct  tagRoadKey 
  {
      int  nType;
      int  nScale;
 
      bool   operator   < ( const  tagRoadKey &  other)  const
      {
          if  (nType  <  other.nType)         // 类型按升序排序
          {
              return   true ;
          }
          else   if  (nType  ==  other.nType)   // 如果类型相同,按比例尺升序排序
          {
              return  nScale  <  other.nScale;
          }
         
          return   false ;
      }
  }ROADKEY;
 
  struct  tagRoadInfo
  {
      tagRoadKey roadKey;
      int         nRoadWidth;
  };
 
  class  CRoadWidthMng
  {
  public :
      CRoadWidthMng();
      virtual   ~ CRoadWidthMng();
 
  public :
      int  GetRoadWidth( int  nRoadType,  int  nScale);  // 根据道路类型、比例尺获取宽度
 
  private :
      void  Init();
 
  private :
      const   int   MIN_SCALE;            // 最小的比例尺
      const   int   DEFAULT_ROAD_WIDTH;   // 如没有找到,返回默认值
 
      map < ROADKEY,  int > m_roadMap;
  };
 
  #endif
 
  ////// //.cpp ////// /
  #include  " CRoadWidthMng.h "
 
  tagRoadInfo roadInfoItem[]  =
  {
      ///////// //高速公路 //////////// //
      {
          {
              10 ,
              12
          },
              16
      },
      {
          {
              10 ,
              11
          },
              12
      },
 
      {
          {
              10 ,
              10
          },
              6
      },
      {
          {
              10 ,
              9
          },
              3
      },
      ////// /国道 /////////////// //
      {
          {
              12 ,
              12
          },
              12
      },
      {
          {
              12 ,
              11
          },
              8
      },
 
      {
          {
              12 ,
              10
          },
              6
      },
      {
          {
              12 ,
              9
          },
              4
      },
      ////// /省道 /////////////// //
      {
          {
              14 ,
              12
          },
              10
      },
      {
          {
              14 ,
              11
          },
              10
      },
 
      {
          {
              14 ,
              10
          },
              6
      },
      {
          {
              14 ,
              9
          },
              4
      },
      ////// /铁路 /////////////// //
      {
          {
              21 ,
              12
          },
              1
      },
      {
          {
              21 ,
              11
          },
              1
      },
 
      {
          {
              21 ,
              10
          },
              1
      },
      {
          {
              21 ,
              9
          },
              1
      },
  };
 
  CRoadWidthMng::CRoadWidthMng()
      :MIN_SCALE( 6 ), DEFAULT_ROAD_WIDTH( 5 )
  {
      Init();
  }
 
  CRoadWidthMng:: ~ CRoadWidthMng()
  {
      m_roadMap.clear();
  }
 
  void  CRoadWidthMng:: Init()
  {
      int  nNum  =   sizeof (roadInfoItem)  /   sizeof (roadInfoItem[ 0 ]);
 
      for  ( int  i  =   0 ; i  <  nNum;  ++ i)
      {
          m_roadMap.insert(make_pair(roadInfoItem[i].roadKey, roadInfoItem[i].nRoadWidth));
      }
  }
 
  int  CRoadWidthMng:: GetRoadWidth( int  nRoadType,  int  nScale)
  {
      if  (nScale  <  MIN_SCALE)
      {
          nScale  =  MIN_SCALE;
      }
 
      map < ROADKEY,  int > ::iterator itor;
 
      int  nValue;
      ROADKEY roadkey;
      roadkey.nType  =  nRoadType;
      roadkey.nScale  =  nScale;
 
      itor  =  m_roadMap.find(roadkey);
 
      if  (itor  !=  m_roadMap.end())
      {
          nValue  =   itor -> second /* nRoadWidth */ ;
      }
      else
      {
          nValue  =   DEFAULT_ROAD_WIDTH;
      }
 
      return  nValue;
  }

你可能感兴趣的:(map中key为结构体的用法)