As I understood all types of boost.variant are parsed into real types (meaning as if boost variant
would after compilation t
You can use the following that both result in std::type_info objects:
together with the member function std::type_info::operator==, to check which type the boost::variant is currently storing. For example,
boost::variant<int, bool, std::string> container;
container = "Hello world";
if (container.type() == typeid(std::string)) {
std::cout << "Found a string: " << boost::get<std::string>(container);
}
else if (container.type() == typeid(int)) {
std::cout << "Found an int: " << boost::get<int>(container);
}
You can use the pointer version of boost::get
. The tutorial has this example:
void times_two( boost::variant< int, std::string > & operand )
{
if ( int* pi = boost::get<int>( &operand ) )
*pi *= 2;
else if ( std::string* pstr = boost::get<std::string>( &operand ) )
*pstr += *pstr;
}
So you use it like you normally would use boost::get
but pass a pointer to a variant instead, and the result is a pointer which is nullptr
if that is not the type currently stored in the variant. It's not useful if that type appears more than once in the list of types in the variant, but that is not very common.
boost.variant
has a .type() function which can return the typeid of the active type, provided you've enabled RTTI.
You could also define a static visitor to perform actions depending on the type of content of the variant, e.g.
struct SomeVisitor : public boost::static_visitor<double>
{
double operator()(const func0& f0) const { return f0(1.0); }
double operator()(const func1& f1) const { return f1(1.0, 1.0); }
double operator()(int integer) const { return integer; }
};
...
std::cout << boost::apply_visitor(SomeVisitor(), v) << std::endl;
v.which()
will return the 0-based index of the type of the object currently held.
When you are retrieving the object your code must use a static type (in order to satisfy the get<T>
function template) to refer to an (effectively) dynamically typed object.
You need to either test for the type (using which()
or type()
) and branch accordingly or use a static visitor. No matter which way you choose, you have to explicitly state the static type that you want to retrieve and it has to match the dynamic type or an exception will be thrown.
One way around this problem is instead of using a variant type directly, use a class which contains a variant type internally and then defines any implicit conversion operators necessary to use the object with minimum fuss.
I have a project called Dynamic C++ which uses this technique.