views:

53

answers:

1

Hi experts,

Since std::pair<std::string, unsigned int> is not defined for __gnu_cxx hash map, how do I create a __gnu_cxx hash map with keys of type std::pair<std::string, unsigned int> and values of type std::pair<int, CBTNODE>? (CBTNODE is typedef as typedef int CBTNODE)

If it's possible, I would really want to substitute std::pair<std::string, unsigned int> with a typedef-ed INDEX (typedef std::pair<std::string, unsigned int> INDEX)

Any help will be much appreciated!

Z.Zen

+2  A: 

This seems to compile and print the right answer (1):

#include <hash_map>
#include <utility>
#include <string>
#include <iostream>

typedef int CBTNODE;
typedef std::pair<std::string, unsigned int> INDEX;
typedef std::pair<int, CBTNODE> Element;

struct pairhash{
    size_t operator()(const INDEX &p) const {
        return
          __gnu_cxx::hash<const char*>()(p.first.c_str()) ^
          __gnu_cxx::hash<unsigned int>()(p.second);
    }
};

int main() {
    __gnu_cxx::hash_map<INDEX, Element, pairhash> x;
    INDEX foo("hi", 0);
    Element bar(1, 2);
    x[foo] = bar;
    std::cout << x[foo].first << "\n";
}

Which was a bit tedious. The issue is that __gnu_cxx::hash doesn't provide a specialization for pair, or for that matter for string either. I believe it follows the SGI API here: http://www.sgi.com/tech/stl/hash.html. So pairhash (or something like it) is needed to provide the missing hash function.

I don't blame you for not spotting that, since the compiler error that this caused was a bit, um, non-obvious. And long.

If you can, you're probably better off using boost::unordered_map. SGI's hash_map is an old API, never adopted into the standard, due to be replaced in C++0x, etc, etc.

Steve Jessop