Creating a static hashmap in C++

In Java, you can initialize and populate a static hashmap:

private static Map<String, MyClass> map = new HashMap<String, MyClass>();
static
{
map.put( “a”, new MyClass( “a”, “b”) );
map.put( “c”, new MyClass( “c”, “a” ) );
}

etc.

Is there an equivalent way with C++ (using ext/hash_map), entirely within a class’s static context?

In C++, classes/structures are not static since they’re just declarations, but you can create a class/structure filled entirely with static members. Each of those static members must be instantiated somewhere. For example:



// Declaration
class MyHashMap
{
public:
    // Constructor/Destructor not necessary
    static void Function1();
    static void Function2();

private:
    static int data1[10];
    static int data2[10];
};

// Instantiation of static member functions
void MyHashMap::Function1()
{
    // Fill with 0's
    for(int i = 0; i < 10; i++)
        data1* = 0;
}

void MyHashMap::Function2()
{
    // Fill with -1
    for(int i = 0; i < 10; i++)
        data2* = -1;
}

// Instantiation of static member data
MyHashMap::data1[] = {1,2,3,4,5,6,7,8,9,10};
MyHashMap::data2[] = {10,9,8,7,6,5,4,3,2,1};


Use the Boost libraries.

Example:



#include <iostream>
#include <string>
#include <boost/unordered_map.hpp>
#include <boost/assign/list_of.hpp>

class StaticMap
{
public:
    static int Get(const std::string& key)
    {
        boost::unordered_map<std::string, int>::const_iterator found =
          s_map.find(key);

        if (found == s_map.end())
        {
            return int();
        }

        return found->second;
    }
private:
    static const boost::unordered_map<std::string, int> s_map;

};

const boost::unordered_map<std::string, int> StaticMap::s_map =
  boost::assign::map_list_of("a", 1)("b", 2)("c", 3);

int main()
{
    std::cout << StaticMap::Get("a") << std::endl;
    std::cout << StaticMap::Get("b") << std::endl;
    std::cout << StaticMap::Get("c") << std::endl;

    return 0;
}


Maybe what you’re looking for is a namespace?



namespace Map
{

// put static variables here

}


In your example, you are just providing a scoping wrapper around globals.

A namespace is just a label that allows the compiler to provide isolation to sections of code, otherwise known as scope. This is most useful when using multiple inheritance of different class collections that have same named members, i.e. in a collection of classes called ‘PorkProducts’ and ‘DairyProducts’, they both have a base class name ‘Eat’. You multiple inherit the classes ‘Bacon’, ‘Eggs’, into your class called ‘Breakfast’. If you called the ‘Eat’ base member function ‘Mmmm()’, the compiler wouldn’t know which one you meant. Are you referring to Bacon or Eggs?

You can specify the base class explicitly: ‘MyPointer->Bacon::Mmmm()’, but what if you decided that you wanted Ham instead? You would have to go through every spot in the code and change ‘MyPointer->Bacon::Mmmm()’ to ‘MyPointer->Ham::Mmmm()’. It would be much easier to use the namespace indicator: ‘MyPointer->PorkProducts::Mmmm()’ and you can change the class you are inheriting from Bacon to Ham without going through a re-edit.