c++stlcontainersheterogeneous

Heterogeneous containers in C++


I saw this nice graphic which classifies which STL container would suit based on different requirements of data such as:

-- Fixed Size Vs Variable size

-- Data of same tyme Vs different type

-- Sorted Vs unsorted data

-- Sequential Vs random access

http://plasmahh.projectiwear.org/cce_clean.svg

I notice in that image, that C++ STL there is no container which is

  1. Variable Size
  2. Heterogenous (data of different types).

Doesn't C++ have something for this?

PS - There can be many permutations made out the different properties of the containers and many others too might not be provided in STL.


Solution

  • Well generally C++ Containers are designed to hold objects of a single type using templates. If you want different types that are all derived from one type you can store a container of pointers (I guess you could also have a container of void* to anything...) e.g. std::vector<MyBaseType*>.

    If you want completely unrelated types, you can store objects that can safely reference those other types, such as boost::any.

    http://www.boost.org/doc/libs/1_47_0/doc/html/any.html

    Some examples off the boost site:

    #include <list>
    #include <boost/any.hpp>
    
    using boost::any_cast;
    typedef std::list<boost::any> many;
    
    void append_int(many & values, int value)
    {
        boost::any to_append = value;
        values.push_back(to_append);
    }
    
    void append_string(many & values, const std::string & value)
    {
        values.push_back(value);
    }
    
    bool is_int(const boost::any & operand)
    {
        return operand.type() == typeid(int);
    }
    bool is_char_ptr(const boost::any & operand)
    {
        try
        {
            any_cast<const char *>(operand);
            return true;
        }
        catch(const boost::bad_any_cast &)
        {
            return false;
        }
    }
    

    boost::variant is similar, but you specify all the allowed types, rather than allowing any type in your container.

    http://www.boost.org/doc/libs/1_47_0/doc/html/variant.html

    std::vector< boost::variant<unsigned, std::string> > vec;
    vec.push_back( 44);
    vec.push_back( "str" );
    vec.push_back( SomthingElse(55, 65) ); //not allowed