[英]Lambda with inner class implementing an interface
我對lambda的經驗還不是很豐富,但是我開始非常喜歡它們,並在有意義的地方和我認為它們可以走的地方使用它們。
無論如何,我有一個Tree
類,它有一個Tree::Visitor
類,帶有一個名為visit(/*args*/)
虛擬回調函數。 該訪問者類在所有節點上進行遞歸遍歷。 通過此回調,我可以從每個節點收集數據(或者更好的是,我可以提取樹的路徑(這基本上就是我使用此功能所做的))。
因此,我使用了一個lambda,並在內部使用一個類,通過從Tree::Visitor
派生實現visit
回調函數。
// 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標准的感覺(也許)。
我試圖在visitTheTree()
內部定義que
,並將其傳遞給MyVisitor
的構造MyVisitor
。 不知何故,這無法正常工作,至少我沒有獲得預期的正確/完整結果。 當我將Priority隊列變量定義為A的成員(如現在)並使用MyVistor中的父指針訪問它時,我得到了正確的結果,一切都很好。
有什么好方法可以在VisitTheTree()中本地定義que
,而不是在A類中將其定義為成員? 我知道我必須通過構造函數傳遞它,因為我無法訪問MyVistor之外的變量(就像這樣)。
順便說一句,我發現了問題C ++ 0x-lambda表達式看起來與Java的匿名內部類相同嗎? 這很接近我的問題。 有趣的是約翰尼斯的答案。
任何提示或想法都將受到歡迎。 感謝您的想法和幫助!
安德烈亞斯,我真的很想為您提供幫助,但是我看不到一種使用您的設計的方法。 我在使用Boost圖形庫時遇到了類似的情況,並且做了以下工作(希望它對您有所幫助):
std::function<RET (/*args*/>
成員,該成員用於對您訪問的每個節點執行操作。我還將使此函數成為visitor構造函數的參數。 我會嘗試提供一些例子,
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傳遞給Visitor,從而提供更好的代碼重用性。
我真的認為您設計中的lambda並未使用[&]
綁定,因此從某種意義上講,它可能是一個通用功能,但我認為它將更加干凈,可重用和高效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.