Baz
Baz

Reputation: 13125

Getter for boost::variant object

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.

Upvotes: 4

Views: 1140

Answers (3)

Nicol Bolas
Nicol Bolas

Reputation: 473252

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

Upvotes: 9

Nim
Nim

Reputation: 33655

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.

Upvotes: 3

Riga
Riga

Reputation: 2139

It is a common approach if there is a possibility that the method can't return an object - make the method returning a bool:

bool get_value(Type& type) {
  if ( /*check variant emptyness*/) // one can use this - http://stackoverflow.com/a/7668530/670719
    return false;
  // else assign type 
}

Comments on your solutions:

a) if you will return Empty you will still have to do a check after a method call. So why adding more types if there is a built-in bool already.

b) Type() can have the same value as a legal variable

c) exception is for something exceptional, but from your description "it is often"

d) your problem is that you can't use Type and at the same time can't return boost::variant, so adding one more type with additional ownership issues brings more questions on what is going on without solving initial issue of clean interface.

Upvotes: 1

Related Questions