Question

Am I required to use a visitor class such as class Visitor : public boost::static_visitor<> with boost::variant?

If not, are there reasons not to use a visitor? Are there reasons to prefer a visitor class?

I ask this question because a visitor class appears a redundant aspect to the use of boost::variant.

Was it helpful?

Solution

You are not forced to use a visitor, you can perfectly query for the underlying type using get<T>().

This leads to such code:

int foo(boost::variant<int, std::string, Bar> const& v) {
    if (int const* i = get<int>(&v)) {
        return *i;
    }
    if (std::string const* s = get<std::string>(&v)) {
        return boost::lexical_cast<int>(*s);
    }
    if (Bar const* b = get<Bar>(&v)) {
        return b->toInt();
    }

    std::abort(); // ?
}

Which is, arguably, ugly... and furthermore has the issue that should you add one type to the variant suddenly you need to inspect every single use of it in the code to check you are not missing a if somewhere.

On the other hand, should you be using a variant, if you ever fail to handle a case (type) you will be notified with a compile-time error.

In my eyes, using boost::static_visitor is infinitely superior... though I have used the get<T>() alternative a couple times; generally when I only need to check one (or two) types and do not care (at all) about all the others. An alternative would be using a visitor with a template <typename T> void operator()(T const&) const; overload, which is not necessarily cleaner.

OTHER TIPS

If want to have some operation on variant, for example some check, than you may want to have it as visitor.

struct to_str : boost::static_visitor<std::string>
{
   template<class T>
   std::string operator()(T const & x) const
   {
      return boost::lexical_cast<std::string>(x);
   }
};

On the other hand if you want, for example check if it int and do something with it, you would probably use boost::get e.g.

if(const int * my_int = boost::get<int>(&my_var)) //no-throw form
{
  //do smth with int
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top