Home > Frameworks > boost::any

boost::any

Now this is a simple and straightforward one.  Many scripting languages have untyped variables, in which you can places values of any kinds.  C++ being a strongly typed language doesn’t have that feature naturally. But Boost brings a simple solution.

There’s different ways such mechanism can be implemented.  One could be that it convert types automatically depending on the context.  For instance, placing a string “55” in a variable, then using it in a math calculation.  In that case, the variable would convert the string into a proper interger of value 55.

Boost seems to already support such automatic type conversion through its lexical_cast framework (which I will cover later when I get to it).  On the contrary, boost::any is implemented to enforce the inherent strong typing of C++.   You can put anything in a boost:any variable (as long as the type support the = operator), but the type have to be specified to extract its value.  Making sure no accidental type conversion occurs.

Around the time I was reading the short documentation on boost::any, I was also in need of such a mechanism in a personal (Objective-C) project: keeping track of one pointer at a time that could be of different types, and having to handle the pointer differently depending of its class.  I could have simply kept a pointer of the nearest common base class type and use introspection (which Objective-C is pretty good at) to retrieve the actual type information.  But it felt like a good opportunity to try boost:any in a real context.

All the include that is required:

#include <boost/any.hpp>

and then all we need is to declare our variable, and put whatever we want in it, for example:

boost::any someValue;
someValue = std::string("This is a test");
//...
someValue = 55;
//...
//etc.

We can easily check for what type of data is contained in the variable like so:

if( someValue.type() == typeid(int) )
{
    // handle it as an int
}
else if( someValue.type() == typeid(std::string) )
{
    // handle it as a string
}

Finally, to extract the value we need to use any_cast<> like so:

std::cout << boost::any_cast<int>(anyValue) << "\n";
or
std::cout << boost::any_cast<std::string>(anyValue).c_str() << "\n";

If an any_cast doesn’t match the actual data type inside the variable, an exception is thrown.  So alternatively we can write:

try
{
    // Do something with:
    any_cast<const char *>(operand);
}
catch(const boost::bad_any_cast &)
{
    // Handle a data type other than "const char *"
}

I don’t see it as a template I will use very often, but I know it will come handy at some point.

– Steve

Advertisements
Categories: Frameworks Tags: , , , ,
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: