我对lambdas不是很有经验但是我开始非常喜欢它们并且在有意义的地方使用它们,并且我认为它们是最佳选择。
无论如何,我有一个类Tree
,它有一个Tree::Visitor
类,有一个名为visit(/*args*/)
的虚拟回调函数。 Visitor类在所有节点上进行递归遍历。通过这个回调,我能够从每个节点收集数据(或者更好的是我可以提取树的路径(这基本上就是我用这个函数做的)。
所以我使用lambda并在里面使用类来实现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
的构造函数传递它。不知怎的,这是行不通的,至少我没有得到我期望的正确/完整的结果。当我将Priority队列变量定义为A的成员(就像现在这样)并使用MyVistor中的父指针访问它时,我得到了正确的结果,一切都很好。
有没有什么好方法可以在VisitTheTree()中本地定义que
,而不是在A类中将其定义为成员?我知道我必须用构造函数传递它,因为我无法访问MyVistor之外的变量(就像这样)。
欢迎任何提示或想法。感谢您的想法和帮助!
答案 0 :(得分:0)
std::function<RET (/*args*/>
成员,该成员用于对您访问的每个节点执行操作。我还要将此函数作为访问者构造函数的参数。我会尝试提供一些例子,
class Tree {
...
typedef std::function<void (/*node and args*/)> visit_fn;
class Visitor {
visit_fn& visitor;
public:
Visitor( visit_fn f ) : visitor( f ) {}
...
};
};
class A {
...
void visit_tree() {
que.clear(); // could also be a local queue object
Visitor vis([&](/*args*/) {
que.push( some_data ); /*I have que because of & in my lambda*/
});
vis.triggerVisit();
// Her I can use my queue member
}
};
现在,如果您有一个通用的方式来访问您的元素,您甚至可以将Functor传递给您的访问者,从而提供更好的代码重用。
我真的认为你设计中的lambda没有使用[&]
绑定,从这个意义上来说,这可能是一个常见的功能,我认为它会更干净,可重用和高效。