I have a boost::variant in my program and I want to check if the variant itself is initialized and also if there is a value contained in one of it's types.
I've tried empty() on the variant, but that doesn't seem to work. Neither does checking against NULL.
Does anybody know how to check for this?
EDIT: Ok, It seems it will never be empty, but there will not always be a value in it's contained types, so how do I check for a no-value situation?
if you see my question regarding never empty guarantee and single storage,
boost::variant
does support a NIL-like value type calledboost::blank
. which will guarantee that variant never uses the heap as backup storageYou can detect which type is stored using
boost::variant<>::which()
which returns an integer index of the binded variant type; so if you use blank as the first type, which() will return 0 when its blanksee the following example
hope this helps
You also can use
boost::variant<boost::blank, int, double, long double> number;
And variant function
empty()
. It returns false if variant always contains exactly one of its bounded types. (See the section called Never-Empty Guarantee for more information.)One method for making sure that you have a well defined variant is to include a "NullType" in your variant list. While it may neccessitate writing more code in the "visitors" you will write to use it, they can throw exceptions to let operators know something is amiss. I'm generally against such runtime checks but sometimes, there really isn't any other way. Suffice to say that:
Then add it as the very first argument to the variant list. As others have said and the boost documentation describes you'll never have a situation where a variant is empty. However, you can do a type check to ensure that you won't ever be able to compile with "NullType" if you don't overload functions or have a runtime exception thrown if you do have a "NullType".
Now your variant:
Boost.Variant has a never-empty guarantee, which means it must always store some value. It's
empty
member is guaranteed to always returnfalse
and exists only for compatibility.You may want to check out Boost.Any instead.
A
boost::variant
is always initialized.If you did not initalized it explicitly, the first item was constructed using its default constructor: