Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX

By submitting your information, you agree that devx.com may send you DevX offers via email, phone and text message, as well as email offers about other products and services that DevX believes may be of interest to you. DevX will process your information in accordance with the Quinstreet Privacy Policy.


Revisiting Heterogeneous Containers -3 : Page 3




Application Security Testing: An Integral Part of DevOps

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++."
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



We have made updates to our Privacy Policy to reflect the implementation of the General Data Protection Regulation.
Thanks for your registration, follow us on our social networks to keep up-to-date