C++ 如何使用Boost.Variant遍历一系列有界类型 结构A { std::string get_string(); }; 结构B { int值; }; typedef boost::变量变量类型; std::向量v; A A; B B; v、 推回(a); v、 推回(b);

C++ 如何使用Boost.Variant遍历一系列有界类型 结构A { std::string get_string(); }; 结构B { int值; }; typedef boost::变量变量类型; std::向量v; A A; B B; v、 推回(a); v、 推回(b);,c++,boost,polymorphism,boost-variant,bounded-types,C++,Boost,Polymorphism,Boost Variant,Bounded Types,我如何遍历v的元素来访问a和b对象 我可以用boost::get完成,但语法非常繁琐 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

我如何遍历v的元素来访问a和b对象

我可以用boost::get完成,但语法非常繁琐

  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);
std::vector::it=v.begin();
while(it!=v.end())
{
如果(A*temp_object=boost::get(&(*it)))
std::无法获取_字符串();
++它;
}
我尝试过使用访问技术,但没有走得太远,代码也不起作用:

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;
}
模板
类获取对象
:public boost::static\u访问者
{
公众:
类型运算符()(类型和i)常量
{
返回i;
}
};
...
while(it!=v.end())
{
一个临时对象=boost::apply_visitor(get_object(),*it);
++它;
}
编辑1

黑客解决方案是:

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;
}
类获取对象
:public boost::static\u访问者
{
公众:
运算符()(常数A&i)常数
{
返回i;
}
A运算符()(常量B&i)常量
{
返回A();
}        
};
编辑:
如果这是UncleBens建议的,那么您可以简单地执行以下操作:

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();
  }        
};
下面是一个使用此访问者的迭代示例

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\u FOREACH(变量类型和vt,v)

就我所知,来访者应该做这项工作。如果您只想获取存储的值,那么
boost::get
(如果我没有弄错的话)是预生成的访问者

例如:

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

因此,您希望遍历对象,并根据变量是否包含A或B,为每个元素调用函数X或Y?但这不总是输出一些内容吗?而在最初的尝试中,仅当对象是A时才会打印一些内容?@UncleBens:您是对的。这次for循环的整个主体都应该在访问者中。正如我所说的,我知道如何使用get,但是如果我必须通过类接口公开它,我会发现语法非常不友好。对不起,如果不使用自定义包装器,它将变得非常干净。例如,我刚刚写了一个这样的例子:
A*A=jam(vt)
jam函数返回一个包装类,该类隐式转换为从提供的变量导出的类型的指针和引用。不必精确定义
boost::static\u visitor
的返回类型。如果我没有弄错,它默认为
void
。@Matthieu:是,您还可以编写
boost::static\u visitor
BOOST_FOREACH(var_types& vt, v)
    cout << apply_visitor(ABVisitor(), vt) << endl;
  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);
  }