Browse DevX
Sign up for e-mail newsletters from DevX


Revisiting Heterogeneous Containers -3 : Page 3




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Creating a Heterogeneous Container
The following example uses a vector of any to store four unrelated objects:

using std::vector; using std::string; using std::make_pair; using std::for_each; int main() { vector<boost::any> bag; bag.push_back(string()); bag.push_back(80); bag.push_back(myclass()); //store a pair bag.push_back(make_pair(string("PAGE_SIZE"), 1024)); for_each(bag.begin(), bag.end(), retrieve); }

bag really looks like a heterogeneous container! But how do you access the elements stored in it? First, access the vector's elements as usual, using iterators (as shown in the example) or the [] notation. Next, use the any_cast function to retrieve the value stored in each element:

using std::string; using std::map; using std::cout; using std::endl; void retrieve(boost::any & a) { if(string *pstr = boost::any_cast<string>(&a)) { cout<<"string is: "<< *pstr <<endl; } else if (int *pi = boost::any_cast <int> (&a)) { cout<<"int: "<< *pi <<endl; } else if ( myclass *pmc = boost::any_cast<myclass>(&a)) { cout<< "myclass: " <<endl; } else if (map <string, int> *pmap =boost::any_cast<map<string, int> >(&a)) { cout<< "map<string, int>: " << pmap->first <<" " << pmap>second >>endl; } else { cout<< "unknown type" << endl; } }

Unlike dynamic_cast, boost::any supports non-polymorphic objects and built-in datatypes as well. There's no need to worry about performance either—as opposed to dynamic_cast, boost::any_cast actually uses static_cast under the hood, so it's pretty efficient.

Additional Member Functions
any's destructor destroys the object stored in it. However, because the destructor calls delete and never delete[], you should wrap pointers to arrays in an appropriate smart pointer before storing them in any.

The empty() member function returns a Boolean value indicating whether the any object contains a value:

boost:any anybody; cout<<anybody.empty()<<endl; //display 'true'

any objects. Finally, the type() member function returns a reference to std::type_info which you can use in a typeid expression:

if (typeid(any1.type())==typeid(int)) { int val=boost::any_cast<int> (any1); }

Safe and Efficient
boost::any brings STL containers closer to the SmallTalk-style concept of heterogeneous containers, with minimal performance overhead and without compromising type-safety. Remember that boost::any is also useful in other frameworks that require indiscriminate types. What's still missing in standard C++ is a reflection library that safely reconstructs objects and their types from a collection.

Danny Kalev is a certified system analyst and software engineer specializing in C++. He was a member of the C++ standards committee between 1997 and 2000 and has since been involved informally in the C++0x standardization process. He is the author of "The ANSI/ISO Professional C++ Programmer's Handbook" and "The Informit C++ Reference Guide: Techniques, Insight, and Practical Advice on C++."
Thanks for your registration, follow us on our social networks to keep up-to-date