在C++编程中,我总是需要使用一些容器来存放一个东西的属性。比如:颜色=红色,重量=32千克,诸如此类。显然,使用映射类来存放这东西,无疑是极好的选择。于是,我使用std::map来做这个事情。多完美啊,看起来一切都很不错:查找,插入,清除,比较,赋值,这些功能都很不错。
突然,我发现个问题:std::map总是会对数据进行自动排序。Oh, My God!老大,我不用你给我排序啊,我要保持属性原来的次序!我在网上翻查了许久,也没找到一个能不排序的办法。倒是有文章说,可以自己传入map<>中的第三个参数,借以屏蔽排序。我试了试,天啊,问题更大了。std::map中的很多函数,比如非常重要的find函数,就是借助已排序好的数据来实现查找的,次序乱了,它也就乱了,最乱的时候会引发程序崩溃。无语,头大。
std::map不行吗?我知道std::map本身是很好的,但我真的只要你不排序就行。
好吧,若不起我还躲不起吗?我换个东西来做:第一时间,我想到了hash_map。据<<STL源码剖析>>介绍,hash_map是不排序的,且操作和std::map类似。OK,就你了。
于是乎,跑到VC 6下试了把。晕菜了,居然#include <hash_map>失败……VC 6没有这个东东?网上一查,果然如此……太打击人了!我是做AutoCAD二次开发的,客户从AutoCAD 2002一直到AutoCAD 2011,我则跟着要从VC 6用到VC 2008,以后还要用VC 2010。 你VC 6中没有hash_map,那我的代码,岂不是不能通行于VS各版本?
好吧,你VC 6中没有,我去VC 2002看看。试试,OK,果然有std::hash_map.GOOD!我把map全部换成了hash_map。结果……编译没通过。上帝啊,你玩我啊?你要我自己手动写哈希函数?
算了,看看VC 2008,试试这里有没有自动的。跑VC 2008去写了一行:std::hash_map,编译报错:hash_map不是std成员。我都快哭了。hash_map,VC 2002中你不是还在std中吗?VC 2008你跑哪里去了?含着热泪,我打开hash_map文件,终于发现,原来正确的是:stdext::hash_map。我无语了,这么个搞法,哪里还有通用性?得,不用试了,我不用hash_map就是。
STL的东西,貌似除了自己用vector<pair>重写映射类,就是屏蔽掉map的比较函数,重写find函数(不过我不敢,谁知道还有哪些函数用到了排序功能呢?我不可能去全部重写吧?)。头大,不写,继续找。
去哪里找?自然是MFC。MFC里不是有CMap吗?
这次我谨慎了些,先看看函数手册。
嗯,不错,查找,插入,清除……嗯??赋值呢??居然没有重载等号???OH,MY GOD,我晕了。
还是试试再说吧。
OK,遍历没问题,插入数值没有问题,根据Key取得变量也没问题。
不要急,问题马上来了。把CMap放入容器,立马出问题。把CMap1赋值给CMap2也立马出问题。
好吧,我试试重载等号:CMap operator = (CMap&, const CMap&)。编译器报错:operator=不能是非静态成员。得,弄个普通函数还不成,非要我继承CMap?郁闷。
还是回归map吧,它排序就排它的序吧。