Имеете static_visitor изменить Boost рекурсивный вариант при его обходе?

Я широко использую вариантный вариант Boost для построения деревьев. Точнее, я анализирую дерево по грамматике, используя Qi Boost, а затем пересекаю дерево, чтобы аннотировать каждый узел целым числом — по крайней мере, это то, что я хочу сделать.

Я только что понял, что так как 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.

3

Решение

Вы можете очень сильно изменить объекты, взятые по ссылке:

    void operator()(int) const { }

void operator()(s_node& b) const {
b.value = 10.0;
}

Видеть это Жить на Колиру, выход:

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";
}
2

Другие решения


По вопросам рекламы [email protected]