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
一个hackish解决方案是:
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();
}
};
答案 0 :(得分:3)
据我所见,访客应该做这项工作。如果您只想获取存储的值,那么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);
}
答案 1 :(得分:1)
修改:
如果像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;