簡體   English   中英

具有內部類的Lambda實現接口

[英]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圖形庫時遇到了類似的情況,並且做了以下工作(希望它對您有所幫助):

  • Visitor具有std::function<RET (/*args*/>成員,該成員用於對您訪問的每個節點執行操作。我還將使此函數成為visitor構造函數的參數。
  • 每次您需要訪問某些節點時,都將通過新的lambda函數作為參數,通過訪問者的新實例進行訪問。

我會嘗試提供一些例子,

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM