让 static_visitor 在遍历 Boost 递归变体时对其进行修改?
Posted
技术标签:
【中文标题】让 static_visitor 在遍历 Boost 递归变体时对其进行修改?【英文标题】:Having a static_visitor modify a Boost recursive variant while traversing it? 【发布时间】:2014-05-12 01:58:23 【问题描述】:我广泛使用 Boost 的变体类型来构建树。更准确地说,我使用 Boost 的 Qi 从语法中解析一棵树,然后我遍历树以用整数注释每个节点 - 至少这是我想要做的。
我刚刚意识到,由于 static_visitor 不作为指针访问节点,所以我不可能修改 value 字段。所以我尝试让 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。
【问题讨论】:
apply_visitor
通过引用接受变体 - 你不应该传递指针ala &tree
...
【参考方案1】:
你可以非常多地修改引用的对象:
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";
【讨论】:
以上是关于让 static_visitor 在遍历 Boost 递归变体时对其进行修改?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 boost::variant 中的另一个 static_visitor 中解析 apply_visitor? [关闭]
boost::variant 将 static_visitor 应用于某些类型