STL map中key为结构体的用法

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

1  typedef  struct  tagRoadKey 
2  {
3       int  nType;
4       int  nScale;
5      }
6  }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容器章节。
改正后的结构体如下:

 1  typedef  struct  tagRoadKey 
 2  {
 3       int  nType;
 4       int  nScale;
 5 
 6       bool   operator   < ( const  tagRoadKey &  other)  const
 7      {
 8           if  (nType  <  other.nType)         // 类型按升序排序
 9          {
10               return   true ;
11          }
12           else   if  (nType  ==  other.nType)   // 如果类型相同,按比例尺升序排序
13          {
14               return  nScale  <  other.nScale;
15          }
16          
17           return   false ;
18      }
19  }ROADKEY;


完整代码如下:

  1  / /.h // /
  2  #ifndef _CROADWIDTHMNG_H_
  3  #define  _CROADWIDTHMNG_H_
  4  #include  < map >
  5 
  6  using   namespace  std;
  7 
  8  /*
  9  说明:根据当前比例尺、道路类型获取对应的道路宽度
 10  */
 11  typedef  struct  tagRoadKey 
 12  {
 13       int  nType;
 14       int  nScale;
 15 
 16       bool   operator   < ( const  tagRoadKey &  other)  const
 17      {
 18           if  (nType  <  other.nType)         // 类型按升序排序
 19          {
 20               return   true ;
 21          }
 22           else   if  (nType  ==  other.nType)   // 如果类型相同,按比例尺升序排序
 23          {
 24               return  nScale  <  other.nScale;
 25          }
 26          
 27           return   false ;
 28      }
 29  }ROADKEY;
 30 
 31  struct  tagRoadInfo
 32  {
 33      tagRoadKey roadKey;
 34       int         nRoadWidth;
 35  };
 36 
 37  class  CRoadWidthMng
 38  {
 39  public :
 40      CRoadWidthMng();
 41       virtual   ~ CRoadWidthMng();
 42 
 43  public :
 44       int  GetRoadWidth( int  nRoadType,  int  nScale);  // 根据道路类型、比例尺获取宽度
 45 
 46  private :
 47       void  Init();
 48 
 49  private :
 50       const   int   MIN_SCALE;            // 最小的比例尺
 51       const   int   DEFAULT_ROAD_WIDTH;   // 如没有找到,返回默认值
 52 
 53      map < ROADKEY,  int > m_roadMap;
 54  };
 55 
 56  #endif
 57 
 58  // //.cpp // /
 59  #include  " CRoadWidthMng.h "
 60 
 61  tagRoadInfo roadInfoItem[]  =
 62  {
 63       / //高速公路 //
 64      {
 65          {
 66               10 ,
 67               12
 68          },
 69               16
 70      },
 71      {
 72          {
 73               10 ,
 74               11
 75          },
 76               12
 77      },
 78 
 79      {
 80          {
 81               10 ,
 82               10
 83          },
 84               6
 85      },
 86      {
 87          {
 88               10 ,
 89               9
 90          },
 91               3
 92      },
 93       // /国道 /// //
 94      {
 95          {
 96               12 ,
 97               12
 98          },
 99               12
100      },
101      {
102          {
103               12 ,
104               11
105          },
106               8
107      },
108 
109      {
110          {
111               12 ,
112               10
113          },
114               6
115      },
116      {
117          {
118               12 ,
119               9
120          },
121               4
122      },
123       // /省道 /// //
124      {
125          {
126               14 ,
127               12
128          },
129               10
130      },
131      {
132          {
133               14 ,
134               11
135          },
136               10
137      },
138 
139      {
140          {
141               14 ,
142               10
143          },
144               6
145      },
146      {
147          {
148               14 ,
149               9
150          },
151               4
152      },
153       // /铁路 /// //
154      {
155          {
156               21 ,
157               12
158          },
159               1
160      },
161      {
162          {
163               21 ,
164               11
165          },
166               1
167      },
168 
169      {
170          {
171               21 ,
172               10
173          },
174               1
175      },
176      {
177          {
178               21 ,
179               9
180          },
181               1
182      },
183  };
184 
185  CRoadWidthMng::CRoadWidthMng()
186      :MIN_SCALE( 6 ), DEFAULT_ROAD_WIDTH( 5 )
187  {
188      Init();
189  }
190 
191  CRoadWidthMng:: ~ CRoadWidthMng()
192  {
193      m_roadMap.clear();
194  }
195 
196  void  CRoadWidthMng:: Init()
197  {
198       int  nNum  =   sizeof (roadInfoItem)  /   sizeof (roadInfoItem[ 0 ]);
199 
200       for  ( int  i  =   0 ; i  <  nNum;  ++ i)
201      {
202          m_roadMap.insert(make_pair(roadInfoItem[i].roadKey, roadInfoItem[i].nRoadWidth));
203      }
204  }
205 
206  int  CRoadWidthMng:: GetRoadWidth( int  nRoadType,  int  nScale)
207  {
208       if  (nScale  <  MIN_SCALE)
209      {
210          nScale  =  MIN_SCALE;
211      }
212 
213      map < ROADKEY,  int > ::iterator itor;
214 
215       int  nValue;
216      ROADKEY roadkey;
217      roadkey.nType  =  nRoadType;
218      roadkey.nScale  =  nScale;
219 
220      itor  =  m_roadMap.find(roadkey);
221 
222       if  (itor  !=  m_roadMap.end())
223      {
224          nValue  =   itor -> second /* nRoadWidth */ ;
225      }
226       else
227      {
228          nValue  =   DEFAULT_ROAD_WIDTH;
229      }
230 
231       return  nValue;
232  }
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值