变体访问器类是必需的吗?

Is the boost::variant visitor class a requirement?

本文关键字:访问      更新时间:2023-10-16

我是否需要使用访客类,如class Visitor : public boost::static_visitor<>与boost::variant?

如果没有,是否有理由不使用访问者?有什么理由更喜欢访客班吗?

我之所以问这个问题,是因为访问者类对于boost::variant的使用似乎是多余的。

您不必强制使用访问器,您可以使用get<T>()完美地查询底层类型。

这会导致这样的代码:

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(); // ?
}

可以说,这是丑陋的…而且还有一个问题,如果你突然向变体添加一种类型,你需要检查它在代码中的每一次使用,以检查你没有在某个地方丢失if

另一方面,如果你使用一个变体,如果你没有处理一个case(类型),你将得到一个编译时错误通知。

在我看来,使用boost::static_visitor是无限优越的…虽然我已经使用get<T>()替代几次;通常情况下,我只需要检查一种(或两种)类型,而不关心(根本)其他类型。另一种方法是使用具有template <typename T> void operator()(T const&) const;过载的访问者,这并不一定更干净。

如果想对变量进行一些操作,例如检查,那么您可能希望将其作为访问者。

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);
   }
};

另一方面,如果你想,例如检查它是否为int并对它做一些事情,你可能会使用boost::get,例如

if(const int * my_int = boost::get<int>(&my_var)) //no-throw form
{
  //do smth with int
}