[ACCEPTED]-how do you make a heterogeneous boost::map?-map

Accepted answer
Score: 39
#include <map>
#include <string>
#include <iostream>
#include <boost/any.hpp>

int main()
{
    try
    {
        std::map<std::string, boost::any> m;
        m["a"]  = 2;
        m["b"]  = static_cast<char const *>("black sheep");

        int i = boost::any_cast<int>(m["a"]);
        std::cout << "I(" << i << ")\n";

        int j = boost::any_cast<int>(m["b"]); // throws exception
        std::cout << "J(" << j << ")\n";
    }
    catch(...)
    {
        std::cout << "Exception\n";
    }

}

0

Score: 10

How can I build a <favorite container> of objects of different types?

You can't, but you can fake it pretty well. In 33 C/C++ all arrays are homogeneous (i.e., the 32 elements are all the same type). However, with 31 an extra layer of indirection you can give 30 the appearance of a heterogeneous container 29 (a heterogeneous container is a container 28 where the contained objects are of different 27 types).

There are two cases with heterogeneous 26 containers.

The first case occurs when all 25 objects you want to store in a container 24 are publicly derived from a common base 23 class. [...]

The second case occurs when 22 the object types are disjoint — they do 21 not share a common base class.
The approach 20 here is to use a handle class. The container 19 is a container of handle objects (by value 18 or by pointer, your choice; by value is 17 easier). Each handle object knows how to 16 "hold on to" (i.e., maintain a 15 pointer to) one of the objects you want 14 to put in the container. You can use either 13 a single handle class with several different 12 types of pointers as instance data, or a 11 hierarchy of handle classes that shadow 10 the various types you wish to contain (requires 9 the container be of handle base class pointers). The 8 downside of this approach is that it opens 7 up the handle class(es) to maintenance every 6 time you change the set of types that can 5 be contained. The benefit is that you can 4 use the handle class(es) to encapsulate 3 most of the ugliness of memory management 2 and object lifetime. Thus using handle objects 1 may be beneficial even in the first case.

Score: 8

Would boost::any do the trick for you?

0

Score: 6

Thank you David, that was what I needed. Here's 1 the working solution.

#include <iostream>
using std::cout;
using std::endl;

#include <map>
#include <boost/any.hpp>

using boost::any_cast;
typedef std::map<std::string, boost::any> t_map;


int main(int argc, char **argv)
{

  t_map map;
  char *pc = "boo yeah!";

  map["a"] = 2.1;
  map["b"] = pc;

  cout << "map contents" << endl;
  cout << any_cast<double>(map["a"]) << endl;
  cout << any_cast<char*>(map["b"]) << endl;

  return 0;
}
Score: 5

If you want a limited set of types to be 1 supported, Boost.Variant should do the trick.

Score: 0

boost any surely works, but I think using 3 Int to type Technology as the key type of 2 fusion map is a better solution. No type 1 erasure and possibly faster

More Related questions