2007年7月12日 星期四

functor 還是 boost 的好用

昨天看到有人貼了幾個 link, 比較 STL、Loki、Boost 的 functor,其中 Boost 的 functor 的評論大概還沒寫,所以沒看到(只有標題)

http://blog.csdn.net/hdqqq/archive/2006/01/25/588348.aspx
http://blog.csdn.net/hdqqq/archive/2006/02/07/593877.aspx

我認為跟本也不用考慮了,Boost 的 functor 以 Boost function + Boost bind 組合,彈性是最強大的。你可以把有 n 個參數的的 function 透過 bind 任意指定其中幾個而成為另一個 boost function(也就是 functor),甚至連順序都可以改變! 底下是一些簡單的範例:

先說明一下,boost function 的宣告型式是這樣的:
function <T> 其中 T 為函式型別。例如你有一個函式接受一個 int 與一個 string,並傳回 bool 值,那麼你的函式宣告會長這樣:
bool func(int, string);

現在若你要宣告一個同樣使用介面的 boost function,你只要寫:
function <bool (int, string)> MyFunc;


很簡單吧!

好,現在進入正題。假設你有一個 function 長這樣:
void f(int , int, char, char, float, float, string, string);

你可以:

1. 宣告一個 boost function, 用法與 f( ) 完全一樣.
function <void(int , int, char, char, float, float, string, string)> f1
= f;

2. 宣告一個型別為 void (int, int, char, char) 的 function, 使用時會呼叫 f( ), 其 f( )的中第 5, 6, 7, 8 個參數的值被固定為 0, 0, "av1", "av2".
function <void(int , int, char, char)> f2
= bind(f, _1, _2, _3, _4, 0, 0, "av1", "av2");

3. 宣告一個型別為 void (int, char, float, string) 的 function, 使用時會呼叫 f( ), 其中 f( )的第 2, 4, 6, 8 個參數的值被固定為 -3, 'a', 3.1416, "av".
function <void(int , char, float, string)> f3
= bind(f, _1, -3, _2, 'a', _3, 3.1416, _4, "av");


4. 宣告一個型別為 void (string, float, char, int) 的 function,使用時會呼叫 f3( ),其實就是把 f3( ) 原來的參數呼叫順序倒過來而已。而 f3( ) 又會呼叫 f( ), 且將它的第 2, 4, 6, 8 個參數的值被固定為 -3, 'a', 3.1416, "av".

function <void(string, float, char, int)> f4
= bind(f3, _4, _3, _2, _1);


上述的 _1, _2, _3, _4 分別代表 bind 後的 function 的第 1, 2, 3, 4 個參數.

使用範例:

f1(0, 1, 'a', 'b', 10.5, 20.1, "foo", "bar") 相當於
f(0, 1, 'a', 'b', 10.5, 20.1, "foo", "bar")


f2(0, 1, 'a', 'b') 相當於
f(0, 1, 'a', 'b', 0, 0, "av1", "av2"")


f3(10, 'x', 98.7, "blog") 相當於
f(10, -3, 'x', 'a', 98.7, 3.1416, "blog", "av")


f4("avhacker", 2.71828183, 'z', 99) 相當於
f(99, -3, 'z', 'a', 2.71828183, 3.1416, "avhacker", "av");


當然,連 member function 也可以這樣玩,而且不必要是
static member function,相當的好用。

註:這篇是從 Yahoo Blog 搬過來的,原發文時間為 2007/01/05 15:02。

沒有留言: