Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getter for boost::variant object

Tags:

c++

boost

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.

like image 284
Baz Avatar asked Dec 16 '22 18:12

Baz


2 Answers

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>.

like image 56
Nicol Bolas Avatar answered Dec 18 '22 08:12

Nicol Bolas


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.

like image 37
Nim Avatar answered Dec 18 '22 06:12

Nim