Look at the last line. This apparently ingenuous line hides a
serious overhead. Having declared the hash_map as <std::string, int>,
when you pass an array of chars to the hash map, it will perform an
implicit conversion from char * to string. So, in that line you are
creating a temporal string, an later copying into it.

The overhead due to the creation of the temporal string, varies
with the std::string implementation. Some implementation will allocate
memory, an memcpy. VC7 implementation of string, doesn't allocate memory
if the size is less than 16 characters. But you have the copy...

This solution doesn't seem to be clean. And you have the
size-overhead of those statics.
A better solution may be using a class like this to avoid the
overhead described:

// HashString is supposed to be used as a key in a HashTable.
// It is used like a normal string but with the added possibility of create it
// as a pointer to an external array of chars without committing copy.
class HashString
{
public:

// Create HashString from a zero terminated array of chars. The creation
// will only perform a copy of the pointer. This constructor must only be
// used for temporal objects.
// \param szName zero terminated array of chars
// \param dontCopy
HashString(const Char *szName, DontCopyEnum dontCopy): m_szPtr(szName)
{
}

// Hash function
// This algorithm (k=33) was first reported by dan bernstein many years ago in
// comp.lang.c. another version of this algorithm (now favored by bernstein) uses
// xor: hash(i) = hash(i - 1) * 33 ^ str[i]; the magic of number 33
// (why it works better than many other constants, prime or not) has never been
// adequately explained.
operator size_t() const
{
UInt32 iHash = 5381;
Int32 c;