作者spider391 (小乖)
看板C_and_CPP
標題[心得] Boost Lambda 使用情境範例
時間Sat Jul 31 16:00:29 2010
在討論之前先介紹一個網頁,裡面有很詳細的 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)
→ x000032001:色碼請用ctrl+c打出*[m或ctrl+u打出*號 07/31 16:04
推 nowar100:推你用心 晚點再來研究細節 XD 07/31 16:56
→ tinlans:boost.lambda 用到這樣離走火入魔其實還早。 07/31 17:31
→ tinlans:它還能加上 if_then_else() 和 switch_statement() 07/31 17:33
→ tinlans:做更多程式流程控制,還能宣告一些 delayed variable 07/31 17:34
→ tinlans:來讓 expression 能存放更多的值,或當作暫存變數用。 07/31 17:35
→ tinlans:但老實說要玩到這樣,不如直接用 C++0x 的 syntax。 07/31 17:35
→ spider391:多謝 tin 大的說明 07/31 18:54
※ 編輯: spider391 來自: 117.19.121.141 (07/31 19:03)
推 avhacker:我始終覺得 lambda 玩到這樣就差不多了,再下去會搞死自己 08/02 01:28
→ avhacker:if_then_else這類較複雜的,出個小錯就有看不錯的錯誤訊息 08/02 01:28
推 purpose:原PO文中的第一個連結,裡面的內容就是 Beyond the C++... 09/16 22:32
→ purpose:補上九九乘法那篇 (15733) 的文章代碼:#1BQ0DAAE 09/16 22:37