乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      慎用C++ std::map 的[]運(yùn)算符

       禁忌石 2019-05-28

      2008年09月18日 13:48:00

      map的[]運(yùn)算符在用法上和我們對(duì)[]常規(guī)理解大有出入,因此也往往很容易造成了使用上的失誤,在這點(diǎn)上我強(qiáng)烈認(rèn)為stl設(shè)計(jì)犯了大錯(cuò)。

      首先看其函數(shù)聲明:

      T& operator[] ( const key_type& x );
      http://www./reference/stl/map/operator[].html 的描述中,該聲明等效于:
      (*((this->insert(make_pair(x,T()))).first)).second
      倏忽的程序員一不留意就會(huì)栽入陷阱,因?yàn)樵谖覀兊某R?guī)理解里,[]操作不應(yīng)該對(duì)本不屬于容器自己的關(guān)鍵字做查詢操作。但
      map卻直接執(zhí)行了一次insert操作。
      看以下代碼:

      #include <iostream>#include <map>using namespace std;class MapManager{public :    typedef map<stringstring> 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;}

      類(lèi)MapManager的設(shè)計(jì)者本來(lái)希望通過(guò)ret(int index)查找關(guān)鍵字的值,但顯然設(shè)計(jì)者這么做實(shí)際上不小心給map加入了新元素
      當(dāng)然,疏忽的地方在于,對(duì)于查詢函數(shù),應(yīng)該加上const保護(hù)類(lèi)成員,這樣至少會(huì)編譯錯(cuò)誤。也就是說(shuō),壓根在這里就不該
      使用[]重載,而是應(yīng)該用find,當(dāng)然,如果find之前沒(méi)有先判斷該key是否存在,那么查詢不存在的key將導(dǎo)致運(yùn)行時(shí)錯(cuò)誤。
      或許[]重載正是為了保護(hù)查詢不存的key時(shí),不會(huì)出現(xiàn)運(yùn)行時(shí)錯(cuò)誤而選擇了insert操作,但這樣似乎也不是好辦法。
      正確寫(xiě)法:

      #include <iostream>#include <map>using namespace std;class MapManager{public :    typedef map<stringstring> 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;}



      另外,說(shuō)說(shuō)另一個(gè)用法:


      #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)

      這里存在的效率差別我就不多說(shuō)了。
      總之,map的[]重載確實(shí)給我們帶來(lái)了編碼上感性上的便利,但總體而言,對(duì)于講究效率和代碼質(zhì)量的程序員,似乎就不那么
      推薦使用了。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類(lèi)似文章 更多