2008年09月18日 13:48:00
map的[]運(yùn)算符在用法上和我們對[]常規(guī)理解大有出入,因此也往往很容易造成了使用上的失誤,在這點(diǎn)上我強(qiáng)烈認(rèn)為stl設(shè)計(jì)犯了大錯。
首先看其函數(shù)聲明:
T& operator[] ( const key_type& x );在
http://www.cplusplus.com/reference/stl/map/operator[].html 的描述中,該聲明等效于:(*((this->insert(make_pair(x,T()))).first)).second倏忽的程序員一不留意就會栽入陷阱,因?yàn)樵谖覀兊某R?guī)理解里,[]操作不應(yīng)該對本不屬于容器自己的關(guān)鍵字做查詢操作。但map卻直接執(zhí)行了一次insert操作??匆韵麓a:#include <iostream>#include <map>using namespace std;class MapManager{public : typedef map<string, string> MapNameToID; string ret(const string& name) { return m_map[name]; } void list() { for ( MapNameToID::iterator iter = m_map.begin(); iter != m_map.end(); ++iter) { cout << "(" << iter->first << ", " << iter->second << ")" << endl; } }private : MapNameToID m_map;};int main(){ MapManager m; cout << m.ret("yao") << endl; cout << m.ret("jian") << endl; m.list(); return 0;}
類MapManager的設(shè)計(jì)者本來希望通過ret(int index)查找關(guān)鍵字的值,但顯然設(shè)計(jì)者這么做實(shí)際上不小心給map加入了新元素當(dāng)然,疏忽的地方在于,對于查詢函數(shù),應(yīng)該加上const保護(hù)類成員,這樣至少會編譯錯誤。也就是說,壓根在這里就不該使用[]重載,而是應(yīng)該用find,當(dāng)然,如果find之前沒有先判斷該key是否存在,那么查詢不存在的key將導(dǎo)致運(yùn)行時(shí)錯誤?;蛟S[]重載正是為了保護(hù)查詢不存的key時(shí),不會出現(xiàn)運(yùn)行時(shí)錯誤而選擇了insert操作,但這樣似乎也不是好辦法。正確寫法:#include <iostream>#include <map>using namespace std;class MapManager{public : typedef map<string, string> MapNameToID; string ret(const string& name) const // 加const { MapNameToID::const_iterator iterRs = m_map.find(name); if (m_map.end() != iterRs) { return iterRs->second; // 用find(name)->second; } else { return ""; } } void list() { for ( MapNameToID::iterator iter = m_map.begin(); iter != m_map.end(); ++iter) { cout << "(" << iter->first << ", " << iter->second << ")" << endl; } }private : MapNameToID m_map;};int main(){ MapManager m; cout << m.ret("yao") << endl; cout << m.ret("jian") << endl; m.list(); return 0;}
另外,說說另一個用法:
#include <iostream>#include <map>using namespace std;class K{public : K() { cout << "K()" << endl; } K(int) { cout << "K(int)" << endl; }};int main(){ map<int, K> mp; K k; mp[1] = K(3); //mp.insert(map<int, K>::value_type(1, K(3))); return 0;}
以上代碼輸出是:K()K()K(int)而直接用被注釋掉的insert的話輸出是:K()K(int)
這里存在的效率差別我就不多說了??傊琺ap的[]重載確實(shí)給我們帶來了編碼上感性上的便利,但總體而言,對于講究效率和代碼質(zhì)量的程序員,似乎就不那么推薦使用了。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請
點(diǎn)擊舉報(bào)。