SGI の hash_map で std::string をキーにする

元々 SGI の map 実装である hash_map ですが、std::string をキーにしようとするとコンパイルが通りません。

手元の coLinux(Linux debian 2.6.17-co-0.8.0 #1 PREEMPT Sun Jul 8 14:00:12 CEST 2007 i686 GNU/Linux)、gcc 4.1.2 な環境で、以下の test.cc だと、

C++:
  1. #include <string>
  2. #include <ext/hash_map>
  3.  
  4. using namespace std;
  5.  
  6. int main(int argc, char* argv[]) {
  7.     __gnu_cxx::hash_map<string, int> m;
  8. }

は g++ test.cc でコンパイルできますが、1 行追加して(以下の 8 行目)、

C++:
  1. #include <string>
  2. #include <ext/hash_map>
  3.  
  4. using namespace std;
  5.  
  6. int main(int argc, char* argv[]) {
  7.     __gnu_cxx::hash_map<string, int> m;
  8.     __gnu_cxx::hash_map<string, int>::iterator it = m.find("hoge");
  9. }

は怒られます。 Tip about STL hash_map and string にもありますが、その実装が std::string をキーとすることを想定していないのが原因。具体的には、この環境だと /usr/include/c++/4.1.2/ext/hash_fun.h に定義がありますが、std::string な値に対してをハッシュ値を計算する実装がありません。なので、それを追加してやって(以下の 6 ~ 15 行目)、

C++:
  1. #include <string>
  2. #include <ext/hash_map>
  3.  
  4. using namespace std;
  5.  
  6. namespace __gnu_cxx {
  7.     template<> struct hash<std::string> {
  8.         size_t operator()(const std::string& x) const {
  9.             return hash<const char*>()(x.c_str());
  10.         }
  11.     };
  12. }
  13.  
  14. int main(int argc, char* argv[]) {
  15.     __gnu_cxx::hash_map<string, int> m;
  16.     __gnu_cxx::hash_map<string, int>::iterator it = m.find("hoge");
  17. }

であれば無事コンパイルが通るよという話でした。

なんつうネタはちょっと探してみればいくらでもありますね。テヘ。


About this entry