Есть такой класс — элемент в некоем дереве.
class element {
collection<element*> children;
collection<element*> visible_children;
void visit_tree( std::function<void(element*)> visitor);
};
Нужно написать функцию visit_tree которая посещает детей ровно один раз для данного visitor.
Специфика: коллекция visible_children может содержать как элементы из children так и какие-то другие, в том числе и из глубины иерархии.
Как бы классическая имплементация использует hash_set для обнаружения факта посещения:
void element::visit_tree( std::function<void(element*)> visitor) {
std::hash_set<uint_ptr> visited;
std::function<void(element*)> worker = [&]( element* el) {
if( visited.has( uint_ptr(el) ) )
return;
visited.put(el);
visitor(el);
children.for_each(worker);
visible_children.for_each(worker);
};
}
Вопрос можно ли как-нибудь обойтись без этого hash_set ?
Я в принципе могу добавить скажем так uint поле в element для маркерных целей.
Проблема осложняется еще тем что visitor функтор в принипе тоже может запускать visit_tree для каких-то других своих целей.
Задача а приниципе сходная с GC mark-n-sweep ситуациями поэтому может кто-то видел более элегантное решение?