Skip to main content

How to make a map of variant in C++

This code is used by RainbruRPG to store any scalar types in a single class instance. It's already in use since revision 254 to save game states values when switching fullscreen or changing screen resolution.
C++ map of variant example

The map class

It's basically a map of boost::variant using std::string as map key. I decided to use function template setter and getter to have a standardized exception-based error handling, but you could have multiple parameter-based specialized getter/setter (void set(bool), void set(int)...).

Here is the example implementation :
#include <boost/variant.hpp>
#include <map>
#include <string>

using namespace std;
using namespace boost;

/** The basic tStateMap value type */
typedef variant<int,float,bool,string> tStateMapType;

/** The map that stores StateSaver properties */
typedef map<std::string, tStateMapType> tStateMap;

/** A property map used to store some GameState values */
class StateSaver

  bool exists(const string&)const;

  template<typename T> void set(const string& key, const T& value)
    if (exists(key))
      throw "Duplicate key";
    mStates[key] = value;

  template<typename T> const T& get(const string& key)const
    if (!exists(key))
      throw "Can't find key";

    return boost::get<T>(mStates.find(key)->second);

  /* Here you have a boost::bad_get exception if you try 
   * to get an existing key using a wrong type
  bool exists(const string& key)const
    if (mStates.find(key) == mStates.end())
      return false;

    return true;

  tStateMap mStates;                 // The property map

How to use it

Since It's a simple template-functions based class, you need to call it with a type specifier :
StateSaver sv;
sv.set<bool>("mykey", true);
bool b = sv.get<bool>("mykey");


This class can be (and is actually) used to store many other complex types. The current implementation in StateSaver.hpp and StateSaver.cpp is actually used by MainMenu::save() to save CEGUI windows position and status using subkeys.


Popular posts from this blog