Saturday, February 9

Using hash_map on GCC

If you have tried to use some STL containers with GCC, such as hash_map:

// error: hash_map: No such file or directory
#include <hash_map>

int
main()
{


// error: ‘hash_map’ is not a member of ‘std’
std::hash_map<int,int> hm;

return
0;
}

Then you have realized that the code above does not compile. That's because on GCC, hash_map is not regarded as a standard container, but rather as a extension included in the __gnu_cxx namespace. In order to use hash_map and other extended containers with a minimum impact in your code (which is very important if it's intended to be cross-platform), you can use the following solution:

#ifdef __GNUC__
#include <ext/hash_map>
#else
#include <hash_map>
#endif


namespace
std
{

using namespace
__gnu_cxx;
}


int
main()
{


std::hash_map<int,int> hm;

return
0;
}
Hope that helps.

4 comments:

Anonymous said...

Hello,

In fact, hash maps are not a part of the C++ standard yet. They have been added to the working draft, and there is an almost complete implementation of the specification which was recently accepted into Boost (http://igaztanaga.drivehq.com/unordered/) that should smooth the transition to C++0x even more.

Cheers!

uiyui said...
This comment has been removed by a blog administrator.
Anonymous said...

Very helpful. Thank you!

Ricardo J. said...

Google has a solution for hash_map.
You must install "sparsehash" (apt-get install sparsehash).
The documentation is here: http://code.google.com/p/google-sparsehash/

Example:


#include <iostream>
#include <google/sparse_hash_map>

using google::sparse_hash_map; /* namespace where class lives by default */
using std::cout;
using std::endl;
using __gnu_cxx::hash; /* or ext::hash, or maybe tr1::hash, depending on your OS */

struct eqstr
{
   bool operator()(const char* s1, const char* s2) const
   {
      return (s1 == s2) || (s1 && s2 && strcmp(s1, s2) == 0);
   }
};

int main()
{
     sparse_hash_map<const char*, int, hash<const char*>, eqstr> months;
     sparse_hash_map<const char*, int, hash<const char*>, eqstr>::iterator It;

     months.set_deleted_key(NULL);
     months["january"] = 31;
     months["february"] = 28;
     months["march"] = 31;
     months["april"] = 30;
     months["may"] = 31;
     months["june"] = 30;
     months["july"] = 31;
     months["august"] = 31;
     months["september"] = 30;
     months["october"] = 31;
     months["november"] = 30;
     months["december"] = 31;

     cout << "september -> " << months["september"] << endl;
     cout << "april     -> " << months["april"] << endl;
     cout << "june      -> " << months["june"] << endl;
     cout << "november  -> " << months["november"] << endl;

     /* Find and erase */
     It = months.find("january");
     if (It != months.end())
     {
        cout << "january found" << endl;
        cout << "erasing january" << endl;
        months.erase(It);

        if (months.find("january") == months.end())
            cout << "january erased" << endl;
        else

            cout << "january NOT erased" << endl;
     }
     else
        cout << "january NOT found" << endl;

     return 0;
}