__gnu_cxx::hash_map使用中的一些問題

來源:互聯網
上載者:User

[STL] __gnu_cxx::hash_map使用中的一些問題,

今天看《libstdc++ manual 20110201》中提到這個hash_map是為了向後相容SGI/HP的代碼,但是已經被廢棄了,取而代之的是C++0x中的unordered_map/unordered_multimap,在tr1檔案夾中(老版本的編譯器一般不帶這個檔案夾)。

==============================================================================


這個不是gcc標準庫的一部分,而是擴充ext中的一個功能,他提供了一個雜湊表的實現。定義如下:

template<class _Key, class _Tp, class _HashFcn = hash<_Key>,<br /> class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> ><br /> class hash_map;<br />

可見,如果定義完整的hash_map,需要提供<key類型,value類型,雜湊函數,key相等判斷函數,value類型記憶體 Clerk>等5個模板參數,由於後三個都有預設值,所以一般我們只需要提供前兩個。

 

1>
定義__gnu_cxx::hash_map<string, int> myHash;不會出錯,然而一旦對myHash進行操作,就會出現編譯錯誤,“instantiated
from here”,這是因為gnu版本的hash_map只實現了有限的幾個hash模板函數(見第三個模板參數,這些函數在hash_fun.h中),而這些函數裡包括hash<const
char*>,但是不包括hash<std::string>的執行個體化。解決辦法是定義雜湊表前自己定義一個執行個體,這樣編譯器就知道調用這個函數了。

namespace __gnu_cxx<br />{<br />template<> struct hash<std::string><br />{<br />size_t operator()(const std::string &s) const{ return hash(s.c_str()); }<br />}<br />}<br />

 

2>
發現了gnu幫我們實現了hash<const char*>/hash<char*>的版本,那麼實際上,有時候就可以直接利用這個版本了。然而還是會出現新的問題:

__gnu_cxx::hash_map<char*, int> myHash;<br />char name1[10] = "panda";<br />char name2[10] = "panda";<br />myHash[name1] = 1;<br />__gnu_cxx::hash_map<char*, int>::iterator hit = myHash.find( name2 );<br />if( myHash.end() == hit ) printf( "Not Find\n" );<br />

你會發現,雖然name1和name2都是panda,但是插入了name1,用name2去尋找時,還是查無結果。這是涉及到第四個模板參數,判斷key相等,預設的是std::equal_to,而這個函數的定義是用operator==來進行判斷的,指標的相等當然就是地址一樣了,而name1和name2的地址顯然不同。解決辦法是用自己指定的函數模板替代預設的。

template <class _Tp><br />struct my_equal_to : public binary_function<_Tp, _Tp, bool><br />{<br /> bool<br /> operator()(const _Tp& __x, const _Tp& __y) const<br /> { return strcmp( __x, __y ) == 0; }<br />};<br />// 定義雜湊表時,用如下方法(這次不能跳過第三個模板參數,所以要指定):<br />__gnu_cxx::hash_map< char*, int, __gnu_cxx::hash<char*>, my_equal_to<char*> > myHash;<br />

 

3>
遍曆__gnu_cxx::hash_map出現了死迴圈,這個問題並不常見,然而遇到了可能真讓人摸不到頭腦。還好我之前見過這篇文章,沒有在這裡陷很久。

http://blog.csdn.net/tototony/article/details/5689882

這個問題簡單說來,就是gnu的實現是,內部有個_M_Cur指標指示當前位置A,每次計算operator++,都用當前位置的key調用hashFunction Compute下一個位置B,如果key傳入hash_map以後,又在外部將其內容破壞,導致hashFunction Compute後的B位置在A位置之前,那麼從B到達A以後,又會跳回B,形成B-A區間的死迴圈。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.