c++boost-variantapply-visitor

Is the boost::variant visitor class a requirement?


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.


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.