我正在广泛使用Boost的变种类型来构建树。更确切地说,我使用Boost的Qi解析语法中的树,然后我遍历树以用整数注释每个节点 - 至少这是我想要做的。
我刚刚意识到由于static_visitor没有作为指针访问节点,所以我无法修改值字段。所以我试着让static_visitor处理变量类型的指针,而不是变体本身。
简化示例:
typedef struct s_node node;
typedef boost::variant<
int,
boost::recursive_wrapper<node>,
> tree;
struct s_node
{
tree left, right;
double value;
explicit s_node(const expr& l, const expr& r) : oper1(l), oper2(r) { value = -1.0; }
};
struct Traversal : boost::static_visitor<void>
{
void operator()(int *i) const { return; }
void operator()(node *b) {
b->value = 10.0;
}
};
但它不起作用。当我尝试做的时候:
Traversal t;
boost::apply_visitor(t, &tree);
我收到错误:
test.cpp:253:21: error: no matching function for call to 'apply_visitor'
...
如何让static_visitor按我的意愿行事?有一个更好的方法吗?目前,我正在考虑的唯一想法是使节点结构中的字段成为指向int的指针,而不是int。
答案 0 :(得分:2)
您可以非常修改通过引用获取的对象:
void operator()(int) const { }
void operator()(s_node& b) const {
b.value = 10.0;
}
查看 Live On Coliru ,输出:
Before: s_node {5, s_node {7, 42 /*value: -1*/} /*value: -1*/}
After: s_node {5, s_node {7, 42 /*value: -1*/} /*value: 10*/}
完整样本:
#include <boost/variant.hpp>
#include <iostream>
struct s_node;
typedef boost::variant<
int,
boost::recursive_wrapper<s_node>
> expr;
struct s_node
{
expr oper1, oper2;
double value;
explicit s_node(const expr& l, const expr& r)
: oper1(l), oper2(r), value(-1) { }
friend std::ostream& operator<<(std::ostream& os, s_node const& n) {
return os << "s_node {" << n.oper1 << ", " << n.oper2 << " /*value: " << n.value << "*/}";
}
};
struct Traversal : boost::static_visitor<void>
{
void operator()(int) const { }
void operator()(s_node& b) const {
b.value = 10.0;
}
};
int main()
{
expr x = s_node(5, s_node(7, 42));
std::cout << "Before: " << x << "\n";
boost::apply_visitor(Traversal(), x);
std::cout << "After: " << x << "\n";
}