如果不想卷入C++ functional的噩夢(mèng)的話(huà),你也可以這么寫(xiě):
struct Op
{
int operator()(int a1, int a2) { return f(a1) + f(a2); }
};
transform(…, Op());
稍微好一點(diǎn),但這種做法也有很?chē)?yán)重的問(wèn)題。
為什么Java加入closure,其實(shí)還是一個(gè)語(yǔ)法問(wèn)題。從嚴(yán)格意義上,Java的anonymous class已經(jīng)可以實(shí)現(xiàn)出一樣的功能了,正如C++的functor一樣。然而,代碼是給人看的,語(yǔ)言是給人用來(lái)寫(xiě)代碼的,代碼的主要代價(jià)在維護(hù),維護(hù)則需要閱讀、理解。寫(xiě)代碼的人不希望多花筆墨來(lái)寫(xiě)那些自己本不關(guān)心的東西,讀代碼的人也希望“所讀即所表”,不想看到代碼里面有什么彎子,是自然語(yǔ)言自然抽象才好呢。
所以,盡管closure是一顆語(yǔ)法糖,但卻是一顆很甜很甜的糖,因?yàn)橛辛薱losure你就可以寫(xiě):
transform(…, <>(a1, a2){ f(a1) + f(a2) });
Simple things should be simple!
此外,closure大的好處還是在于對(duì)局部變量的方便的引用,設(shè)想我們想要?jiǎng)?chuàng)建的表達(dá)式是:
int weight1 = 0.3, weight2 = 0.6;
transform(…, f(_1)*weight1 + f(_2)*weight2);
當(dāng)然,上面的語(yǔ)句是非法的,不過(guò)使用closure便可以寫(xiě)成:
int weight1 = 0.3, weight2 = 0.6;
transform(…, <&>(_1, _2){ f(_1)*weight1 + f(_2)*weight2 } );
用functor class來(lái)實(shí)現(xiàn)同樣的功能則要麻煩許多,一旦麻煩,就會(huì)error-prone,一旦error-prone,就會(huì)消耗人力,而人力,就是金錢(qián)。
C++09也有希望加入lambda,不過(guò)這是另一個(gè)話(huà)題,下回再說(shuō)。
The Real Deal——variadic templates
C++的callback類(lèi),google一下,沒(méi)有一打也有半打。其中尤數(shù)boost.function實(shí)現(xiàn)得最為靈活周到。然而,就在其靈活周到的接口下面,卻是讓人不忍卒讀的實(shí)現(xiàn);03年的時(shí)候我寫(xiě)的第一篇boost源碼剖析就是boost.function的,當(dāng)時(shí)還覺(jué)得能看懂那樣的代碼牛得不行...話(huà)說(shuō)回來(lái),那篇文章主要剖析了兩個(gè)方面,一個(gè)是它對(duì)不同參數(shù)的函數(shù)類(lèi)型是如何處理的,第二個(gè)是一個(gè)type-erase設(shè)施。其中第一個(gè)方面就占去了大部分的篇幅。
簡(jiǎn)而言之,要實(shí)現(xiàn)一個(gè)泛型的callback類(lèi),就必須實(shí)現(xiàn)以下最常見(jiàn)的應(yīng)用場(chǎng)景:
function caller = f;
int r = caller(1, 2); // call f
為此function類(lèi)模板里面肯定要有一個(gè)operator(),然而,接下來(lái),如何定義這個(gè)operator()就成了問(wèn)題:
template
class function
{
operator()(???);
};
struct Op
{
int operator()(int a1, int a2) { return f(a1) + f(a2); }
};
transform(…, Op());
稍微好一點(diǎn),但這種做法也有很?chē)?yán)重的問(wèn)題。
為什么Java加入closure,其實(shí)還是一個(gè)語(yǔ)法問(wèn)題。從嚴(yán)格意義上,Java的anonymous class已經(jīng)可以實(shí)現(xiàn)出一樣的功能了,正如C++的functor一樣。然而,代碼是給人看的,語(yǔ)言是給人用來(lái)寫(xiě)代碼的,代碼的主要代價(jià)在維護(hù),維護(hù)則需要閱讀、理解。寫(xiě)代碼的人不希望多花筆墨來(lái)寫(xiě)那些自己本不關(guān)心的東西,讀代碼的人也希望“所讀即所表”,不想看到代碼里面有什么彎子,是自然語(yǔ)言自然抽象才好呢。
所以,盡管closure是一顆語(yǔ)法糖,但卻是一顆很甜很甜的糖,因?yàn)橛辛薱losure你就可以寫(xiě):
transform(…, <>(a1, a2){ f(a1) + f(a2) });
Simple things should be simple!
此外,closure大的好處還是在于對(duì)局部變量的方便的引用,設(shè)想我們想要?jiǎng)?chuàng)建的表達(dá)式是:
int weight1 = 0.3, weight2 = 0.6;
transform(…, f(_1)*weight1 + f(_2)*weight2);
當(dāng)然,上面的語(yǔ)句是非法的,不過(guò)使用closure便可以寫(xiě)成:
int weight1 = 0.3, weight2 = 0.6;
transform(…, <&>(_1, _2){ f(_1)*weight1 + f(_2)*weight2 } );
用functor class來(lái)實(shí)現(xiàn)同樣的功能則要麻煩許多,一旦麻煩,就會(huì)error-prone,一旦error-prone,就會(huì)消耗人力,而人力,就是金錢(qián)。
C++09也有希望加入lambda,不過(guò)這是另一個(gè)話(huà)題,下回再說(shuō)。
The Real Deal——variadic templates
C++的callback類(lèi),google一下,沒(méi)有一打也有半打。其中尤數(shù)boost.function實(shí)現(xiàn)得最為靈活周到。然而,就在其靈活周到的接口下面,卻是讓人不忍卒讀的實(shí)現(xiàn);03年的時(shí)候我寫(xiě)的第一篇boost源碼剖析就是boost.function的,當(dāng)時(shí)還覺(jué)得能看懂那樣的代碼牛得不行...話(huà)說(shuō)回來(lái),那篇文章主要剖析了兩個(gè)方面,一個(gè)是它對(duì)不同參數(shù)的函數(shù)類(lèi)型是如何處理的,第二個(gè)是一個(gè)type-erase設(shè)施。其中第一個(gè)方面就占去了大部分的篇幅。
簡(jiǎn)而言之,要實(shí)現(xiàn)一個(gè)泛型的callback類(lèi),就必須實(shí)現(xiàn)以下最常見(jiàn)的應(yīng)用場(chǎng)景:
function caller = f;
int r = caller(1, 2); // call f
為此function類(lèi)模板里面肯定要有一個(gè)operator(),然而,接下來(lái),如何定義這個(gè)operator()就成了問(wèn)題:
template
class function
{
operator()(???);
};

