如何使用 Boost.Variant 迭代一系列有界类型

发布于 2024-09-06 11:32:45 字数 1179 浏览 6 评论 0原文

  struct A
  {
    std::string get_string();
  }; 

  struct B
  {
    int value;
  }; 

  typedef boost::variant<A,B> var_types;
  std::vector<var_types> v;

  A a;
  B b;

  v.push_back(a);
  v.push_back(b);

如何迭代 v 的元素来访问 a 和 b 对象?

我可以使用 boost::get 来做到这一点,但语法确实很麻烦。:

std::vector<var_types>:: it = v.begin();
while(it != v.end())
{
    if(A* temp_object = boost::get<A>(&(*it)))    
      std::cout << temp_object->get_string();
    ++it;
}

我尝试使用访问技术,但我没有走得太远,代码无法正常工作:

template<typename Type>
class get_object
  : public boost::static_visitor<Type>
{
public:

  Type operator()(Type & i) const
  {
    return i;
  }

};

...

while(it != v.end())
{
    A temp_object = boost::apply_visitor(get_object<A>(),*it);
    ++it;
}

编辑1< /strong>

一个黑客解决方案是:

class get_object
  : public boost::static_visitor<A>
{
public:

  A operator()(const A & i) const
  {
    return i;
  }

  A operator()(const B& i) const
  {
    return A();
  }        
};
  struct A
  {
    std::string get_string();
  }; 

  struct B
  {
    int value;
  }; 

  typedef boost::variant<A,B> var_types;
  std::vector<var_types> v;

  A a;
  B b;

  v.push_back(a);
  v.push_back(b);

How can I iterate iterate through the elements of v to get access to the a and b objects ?

I'm able to do it with boost::get but the syntax is really cumbersome.:

std::vector<var_types>:: it = v.begin();
while(it != v.end())
{
    if(A* temp_object = boost::get<A>(&(*it)))    
      std::cout << temp_object->get_string();
    ++it;
}

I've tried to use the visitation technique but I didn't get too far and the code is not working :

template<typename Type>
class get_object
  : public boost::static_visitor<Type>
{
public:

  Type operator()(Type & i) const
  {
    return i;
  }

};

...

while(it != v.end())
{
    A temp_object = boost::apply_visitor(get_object<A>(),*it);
    ++it;
}

EDIT 1

A hackish solution is :

class get_object
  : public boost::static_visitor<A>
{
public:

  A operator()(const A & i) const
  {
    return i;
  }

  A operator()(const B& i) const
  {
    return A();
  }        
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱她像谁 2024-09-13 11:32:45

据我所知,访客应该完成这项工作。如果您只是想获取存储的值,那么 boost::get - 如果我没记错的话 - 是预制的访问者。

示例:

  struct print_if_a : boost::static_visitor<void>
  {
    void operator()(A& a) const { std::cout << a.get_string() << '\n'; } //alas, get_string is non-const 
    void operator()(const B&) const {} //does nothing, up to optimizer
  };

用法:

  BOOST_FOREACH(var_types& obj, v) {
    boost::apply_visitor(print_if_a(), obj);
  }

As far as I can see, the visitor is supposed to do the work. If you just want to get the stored value, then boost::get - if I'm not mistaken - is the pre-made visitor for that.

Example:

  struct print_if_a : boost::static_visitor<void>
  {
    void operator()(A& a) const { std::cout << a.get_string() << '\n'; } //alas, get_string is non-const 
    void operator()(const B&) const {} //does nothing, up to optimizer
  };

Usage:

  BOOST_FOREACH(var_types& obj, v) {
    boost::apply_visitor(print_if_a(), obj);
  }
江心雾 2024-09-13 11:32:45

编辑:
如果正如UncleBens建议的那样,那么你可以简单地这样做:

BOOST_FOREACH(var_types& vt, v) {
    if (vt.which() == 0)  
        cout << get<A>(vt).get_string() << endl;
}

原始:
static_vistor 的模板参数是其方法的返回类型。这意味着这两个类需要为单个访问者共享公共返回类型。它应该看起来像这样:

class ABVisitor : public static_visitor<string> {
public:
    string operator()(const A& a) const {
        return a.get_string();
    }
    string operator()(const B& b) const {
        return lexical_cast<string>(b.value);
    }
};

这是使用此访问者进行迭代的示例。

BOOST_FOREACH(var_types& vt, v)
    cout << apply_visitor(ABVisitor(), vt) << endl;

Edit:
If it's as UncleBens suggests, then you can simply do this:

BOOST_FOREACH(var_types& vt, v) {
    if (vt.which() == 0)  
        cout << get<A>(vt).get_string() << endl;
}

Original:
The template parameter for static_vistor is the return type of its methods. This means the two classes need to share a common return type for a single visitor. It should look something like this:

class ABVisitor : public static_visitor<string> {
public:
    string operator()(const A& a) const {
        return a.get_string();
    }
    string operator()(const B& b) const {
        return lexical_cast<string>(b.value);
    }
};

Here's an example of iteration using this visitor.

BOOST_FOREACH(var_types& vt, v)
    cout << apply_visitor(ABVisitor(), vt) << endl;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文