[心得] Boost Lambda 使用情境範例

看板C_and_CPP作者 (小乖)時間15年前 (2010/07/31 08:00), 編輯推噓3(3010)
留言13則, 6人參與, 最新討論串1/1
在討論之前先介紹一個網頁,裡面有很詳細的 Boost Lambda 說明 http://dev.firnow.com/course/3_program/c++/cppjs/20100120/192992.html 最早看到 Lambda 是在 15733 篇中 A 大寫了一個 九九乘法表給發問者 (不知道發問者看了以後是甚麼樣的心情XD) 以下連結有講一些 C++0x 的 Lambda Expression 的使用方式(最後十幾分鐘吧) http://channel9.msdn.com/shows/Going+Deep/C9-Lectures-Introduction-to-STL-with-Stephan-T-Lavavej/ 17912 和 17917 是討論如何用 Boost 的 Lambda 取代 C++0x Lambda 的功能 畢竟很多 compiler 還沒有實作此功能 (感謝 T 大) =================================================================== 我最近寫了一個簡單的 console 框架,框架內有數個 Panel (利用容器實現) Panel::display() 可以畫出 panel Console::show() 把所有 panel display 出來。 以下是簡化的程式碼 class Panel{ string name; public: Panel(std::string name = "") : name(name) {} string get_name() { return name;} virtual void display() { std::cout << name;} //簡化輸出 }; class ConsoleFrameWork { typedef map<string, shared_ptr<Panel> > PanelMap; PanelMap panels; string title; public: ConsoleFrameWork(string title):title(title) {} void init() {} void add(shared_ptr<Panel> p) { panels[p->get_name()] = p; Panel(std::string name = "") : name(name) {} string get_name() { return name;} virtual void display() { std::cout << name;} //簡化輸出 }; class ConsoleFrameWork { typedef map<string, shared_ptr<Panel> > PanelMap; PanelMap panels; string title; public: ConsoleFrameWork(string title):title(title) {} void init() {} void add(shared_ptr<Panel> p) { panels[p->get_name()] = p; } void show(); }; int main(){ shared_ptr<ConsoleFrameWork> cfw(new ConsoleFrameWork("my framework <( ̄︶ ̄)/")); cfw->init(); cfw->add(shared_ptr<Panel > (new Panel("menu_1"))); cfw->add(shared_ptr<Panel > (new Panel("menu_2"))); cfw->add(shared_ptr<Panel > (new Panel("menu_3"))); cfw->show(); } ============================================== Note: 1.此程式我使用 shared_ptr 來避掉手工 delete 2.我利用 map 當作我的容器,這樣我就可以用名稱找到對應的 Panel eq. panels["menu_1"]->display(); 3.重點在於 ConsoleFrameWork::show 的實作 若是使用 STL 的實作方式 void ConsoleFrameWork::show() { PanelMap::iterator it = panels.begin(); for(;it!=panels.end();++it) it->second->display(); } 這實作法算是輕鬆愉快,但能用 for 迴圈的通常都會用 STL 的 for_each 代替 void ConsoleFrameWork::show() { std::for_each(panels.begin(), panels.end(), m??? ); } ??? 符號內通常要塞的是函式物件但這樣會讓實作散布在別處 (很不好看) 這時候就是 Boost Lambda 派上用場的時候了。但這裡的難處是 1. 我用了 map (map<string, shared_ptr<Panel> >) 2. map 的 second 型別是 shared_ptr<Panel> 我花了很多時間在想怎麼用 Boost Lambda 去實現 = =" 最後終於試出來 void ConsoleFrameWork::show() { std::for_each(panels.begin(), panels.end(), bind(&Panel::display, bind(&shared_ptr<Panel>::get, // 取得 Panel* bind(&PanelMap::value_type::second, _1)) // 取得 shared_ptr<Panel> ) ); } 不過雖然實作出來了很高興,但是 code 很 ... 寫出這種 code 不知道交接的人看不看得懂 @@" 大概就像 1772 篇中 g 大所講的,有些走火入魔了吧 XD -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 115.81.102.28 ※ 編輯: spider391 來自: 115.81.102.28 (07/31 16:04)

07/31 16:04, , 1F
色碼請用ctrl+c打出*[m或ctrl+u打出*號
07/31 16:04, 1F

07/31 16:56, , 2F
推你用心 晚點再來研究細節 XD
07/31 16:56, 2F

07/31 17:31, , 3F
boost.lambda 用到這樣離走火入魔其實還早。
07/31 17:31, 3F

07/31 17:33, , 4F
它還能加上 if_then_else() 和 switch_statement()
07/31 17:33, 4F

07/31 17:34, , 5F
做更多程式流程控制,還能宣告一些 delayed variable
07/31 17:34, 5F

07/31 17:35, , 6F
來讓 expression 能存放更多的值,或當作暫存變數用。
07/31 17:35, 6F

07/31 17:35, , 7F
但老實說要玩到這樣,不如直接用 C++0x 的 syntax。
07/31 17:35, 7F

07/31 18:54, , 8F
多謝 tin 大的說明
07/31 18:54, 8F
※ 編輯: spider391 來自: 117.19.121.141 (07/31 19:03)

08/02 01:28, , 9F
我始終覺得 lambda 玩到這樣就差不多了,再下去會搞死自己
08/02 01:28, 9F

08/02 01:28, , 10F
if_then_else這類較複雜的,出個小錯就有看不錯的錯誤訊息
08/02 01:28, 10F

09/16 22:32, , 11F
原PO文中的第一個連結,裡面的內容就是 Beyond the C++...
09/16 22:32, 11F

09/16 22:33, , 12F
一書的中文版剪貼出來的內容 http://tinyurl.com/2urjfs5
09/16 22:33, 12F

09/16 22:37, , 13F
補上九九乘法那篇 (15733) 的文章代碼:#1BQ0DAAE
09/16 22:37, 13F
文章代碼(AID): #1CKzWW3H (C_and_CPP)