Я еще не очень опытен с лямбдами, но я очень люблю их и использую их там, где это имеет смысл, и где я чувствую, что они - путь.Лямбда с внутренним классом, реализующим интерфейс
В любом случае, у меня есть класс Tree
, который имеет класс Tree::Visitor
с одной функцией виртуального обратного вызова, называемой visit(/*args*/)
. Этот класс Visitor выполняет рекурсивную прогулку по всем узлам. С этим обратным вызовом я могу собирать данные с каждого узла (или лучше я могу извлечь пути дерева (что в основном я делаю с этой функцией).
Так что я беру лямбду и внутри я использую класс для реализовать функцию visit
обратного вызова, выводя из Tree::Visitor
.
// Tree class, a rough view how it looks
class Tree {
// ...
// Visitor class for recursive walking the tree
class Visitor {
//
void count(/* ... */) {
// in here the implemented visit(/*args*/) fct is called
}
// ...
void triggerVisit() {
// ...
count(/* ... */);
// ...
}
// visitor callback
virtual void visit(/* args */) = 0;
};
};
class A {
Tree tree;
PriorityQueue que;
A() : tree(), que(maxEntries) {}
// first build the tree ...
void buildTheTree() {
tree.buildTree();
}
// walk the tree
void visitTheTree() {
std::shared_ptr<Tree::Visitor>(
[&]()->Tree::Visitor * {
// this class implements visit(/*args*/)
class MyVisitor : public Tree::Visitor {
A& parent; // pointer to A
Myvisitor(A& p)
: Tree::Visitor(p.tree), parent(p) {}
// implementation
virtual void visit(/* args */) {
// ... get somedata
if (/* condition true */) {
parent.que.push(somedata);
}
}
};
return new MyVisitor(*this);
}()
)->triggerVisit();
// get the collected data from que
while(que.size() > 0) {
// ...
}
}
};
в основном это то, что у меня есть, и она работает без проблем.
у меня есть приоритет очереди que
, которую я использую для хранения somedata
, которые являются n
верхние набранные узлы дерево. В настоящее время que
определяется как член класса A
, который мне не нравится, потому что мне просто нужно собирать данные внутри члена visitTheTree, поэтому он может быть скорее локальной переменной Так что мой вопрос - это скорее вопрос дизайна/стиль, и у меня такое чувство, что я скучаю по стандарту C++ 11 (возможно).
Я попытался определить que
внутри visitTheTree()
и передать его конструктору MyVisitor
. Как-то это работает некорректно, по крайней мере, я не получу надлежащих/полных результатов, которые я ожидаю. Когда я определяю переменную queue Priority как член A (как она есть сейчас) и обращается к ней с родительским указателем в MyVistor, я получаю правильные результаты, и все в порядке.
Есть ли хороший способ определить que
локально в VisitTheTree() вместо определения его в классе A в качестве члена? Я знаю, что мне нужно передать его конструктору, поскольку я не могу получить доступ к переменным за пределами MyVistor (точно так же).
BTW, я нашел вопрос C++0x - lambda expression does look same as Java's anonymous inner class?, который близок к проблеме/вопросу, который у меня есть. Интересен ответ от Йоханнеса.
Любые намеки или идеи приветствуются. Спасибо за ваши мысли и помощь!
Есть ли вообще с нуля вариант? У меня создалось впечатление, что много кода, который вы наметили, не обязательно - я бы зашел так далеко, чтобы сказать, что интересные части - это то, что вы оставили. Вы знакомы со сгибом (который обычно принимает вид 'std :: accumulate' в C++)? Это может быть подходящим способом объединения вашего результата при просмотре данных. Что-то еще может быть уместным, но зависит от того, как вы просматриваете данные и какой результат вы хотите. Это недостающие интересные биты. –
@LucDanton Я никогда не использовал std :: accumulate, я думаю, что не могу использовать его в этом случае. Возможно, если бы у меня был контейнер (например, вектор объектов), я мог бы пойти именно так. Я доволен общим дизайном и не думаю о переписывании дерева, потому что он работает хорошо, как есть. Я просто думаю об этой части выше, которая собирает данные с посетителем, может быть, нет другого способа, как сейчас, мне просто интересно, могу ли я как-то переместить переменную 'que' в локальную переменную внутри' visitTheTree', так как мне просто нужно это там. –
Я не рекомендовал использовать 'std :: accumulate'. –