[心得] Boost Lambda 使用情境範例
在討論之前先介紹一個網頁,裡面有很詳細的 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
07/31 16:04, 1F
推
07/31 16:56, , 2F
07/31 16:56, 2F
→
07/31 17:31, , 3F
07/31 17:31, 3F
→
07/31 17:33, , 4F
07/31 17:33, 4F
→
07/31 17:34, , 5F
07/31 17:34, 5F
→
07/31 17:35, , 6F
07/31 17:35, 6F
→
07/31 17:35, , 7F
07/31 17:35, 7F
→
07/31 18:54, , 8F
07/31 18:54, 8F
※ 編輯: spider391 來自: 117.19.121.141 (07/31 19:03)
推
08/02 01:28, , 9F
08/02 01:28, 9F
→
08/02 01:28, , 10F
08/02 01:28, 10F
推
09/16 22:32, , 11F
09/16 22:32, 11F
→
09/16 22:33, , 12F
09/16 22:33, 12F
→
09/16 22:37, , 13F
09/16 22:37, 13F