tags:

views:

472

answers:

6

This is my first time making a hash table. I'm trying to associate strings (the keys) with pointers to objects (the data) of class Strain.

// Simulation.h
#include <ext/hash_map>
using namespace __gnu_cxx;

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

...
hash_map< const char *, Strain *, hash< const char * >, struct eqstr > liveStrainTable;

In the Simulation.cpp file, I attempt to initialize the table:

string MRCA;
for ( int b = 0; b < SEQ_LENGTH; b++ ) {
  int randBase = rgen.uniform(0,NUM_BASES); 
  MRCA.push_back( BASES[ randBase ] );
}
Strain * firstStrainPtr;
firstStrainPtr = new Strain( idCtr, MRCA, NUM_STEPS );
liveStrainTable[ MRCA ]= firstStrainPtr;

I get an error message that reads "no match for ‘operator[]’ in ‘((Simulation*)this)->Simulation::liveStrainTable[MRCA]’." I've also tried using "liveStrainTable.insert(...)" in different ways, to no avail.

Would really love some help on this. I'm having a difficult time understanding the syntax appropriate for SGI hash_map, and the SGI reference barely clarifies anything for me. Thanks.

+2  A: 

Try liveStrainTable[ MRCA.c_str() ]= firstStrainPtr;. It expects const char * as type of key value, but MRCA has type string.

Another way is to change liveStrainTable to:

hash_map< string, Strain *, hash<string>, eqstr > liveStrainTable;
Kirill V. Lyadvinsky
A: 

The hash_map is defined with const char * as the key type and you are using an std::string as the key when accessing. These are 2 different types, the template did not build an operator for the second type, so this is an error. Use std::string for the hashmap definition or use MRCA.c_str()

kidnamedlox
A: 

Right now, you have a type mis-match. You're passing MRCA (a string) where a char const * is expected. You can either use c_str() to get a char const * from the string, or (far better) change the definition of your hash table to take a string as its key type.

Jerry Coffin
+2  A: 

Others answered your direct question, but may I suggest using unordered_map instead - it's coming with the next version of the STL and is supported by all major compilers.

Nikolai N Fetissov
What advantage does that have?
Paul Nathan
Not using namespace with two leading underscores :)
Nikolai N Fetissov
A: 

Thank you for catching this! It's still not working, unfortunately... I now have

struct eqstr {
  bool operator()(string s1, string s2) const {
    return ( s1.compare(s2) == 0 );
  }
};

  hash_map< string, Strain *, hash< string >, eqstr > liveStrainTable;

and

  liveStrainTable[ MRCA ]= firstStrainPtr;

but now I'm getting a "no match for call to '(const __gnu_cxx::hash) (const std::basic_string, std::allocator >&)’"

I feel like there might be something fundamental about strings and chars that I'm missing.

Sarah
Ah, so I see that strings are not supported with sgi's hash. I will have to revert to char*.
Sarah
A: 

hash_map is not part of STL. There's no implementation provided for hash, or in other words, the hash_map can't hash strings by default. You need your own hash function. T

Try:

typedef struct {
  size_t operator()( const string& str ) const {
     return __gnu_cxx::__stl_hash_string( str.c_str() );
  }
} strhash;

hash_map< string, Strain *, strhash, eqstr > liveStrainTable;
jdoe
**AWESOME!** Thank you. The "liveStrain[MRCA]=firstStrainPtr;" appears to work--I will start writing all the other operations now. I can't wait until hash_map/unordered_map is part of STL and can handle strings.
Sarah
"I can't wait until hash_map/unordered_map is part of STL" Actually it is to become part of the standard library. Most (but not all) of the STL became a part of the std lib at the end of the 90ies. There's many other parts of the std lib, though (strings, streams...), so "STL" is not a synonym for "standard library".
sbi
Also, it's actually quite probable that your std lib already provides `unordered_map` in the namespace `std::tr1`. TR1 (Technical Report 1) lists quite a few libraries that were supposed to become part of the next standard and encouraged vendors to provide them. It was widely adopted. If your std lib doesn't have it, there's an implementation among the boost libraries at http::www.boost.org.
sbi