I have a getter object that returns an object of type Type, defined as follows:
typedef boost::variant<int, std::string> Empty;
It is often the case that I will have neither an int nor a string to return and will have to instead return an empty state. How do you think I return this state?
a) typedef an Empty type and add it to the variant: boost::variant<int, std::string, Empty>
.
b) return Type()
c) Cast an exception
d) return a boost::shared_ptr, which points to NULL in the case of empty.
The correct answer is to use boost::blank
for a variant that can have nothing in it. Thus, your variant typedef looks like this:
typedef boost::variant<boost::blank, int, std::string> Empty;
blank
is designed specifically for this, and variant
has special code based on it. By using it, you get a no-memory-allocation guarantee on copying (if the members don't allocate on copy). So that's good.
Since your variant can be "empty", it is important that all of your processing visitors can handle it. It's often more convenient to add an additional visitor pathway than to have a number of conditionals based on an optional
or something. The different code pathways will be localized to the visitors, which often makes more sense than an optional<variant>
.
Wrap it in a boost::optional
, this has a simple test (convertible to boolean) to determine if there is a valid value assigned - then you don't need to pollute your variant with an "empty" state. e.g.
boost::optional<boost::variant<... > > some_func()
{
:
}
Remember to use in place construction in your function when you actually need to return something.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With