現(xiàn)在,我們想實現(xiàn)一個元函數(shù),可以返回char類型指定層數(shù)的指針類型。
template<int N>
struct CharPointer
{
using Result = typename Times<N, char, PointerOf>::Result;
};
如上,我們定義了元函數(shù)CharPointer,它是一個int型單參元函數(shù)。它的實現(xiàn)調(diào)用了Times,將其第二和第三個參數(shù)分別固定為char和PointerOf。
借助于繼承的特性,上面的代碼可以簡化為:
template<int N>
struct CharPointer :Times<N, char, PointerOf>
{
};
這種定義元函數(shù)的方式叫做元函數(shù)轉(zhuǎn)發(fā)。
如果借助using關(guān)鍵字,可以實現(xiàn)得更加簡單:
template<int N> using CharPointer = Times<N, char, PointerOf>;
這里我們直接對Times綁定第二和第三個參數(shù)后為其起了別名CharPointer。
在函數(shù)式編程里面,有個概念叫做函數(shù)柯里化(currying),是指一個函數(shù)接收部分參數(shù)后,并不立即求值,而是繼續(xù)返回另一個函數(shù)。
如下Haskell代碼定義了一個三數(shù)相乘的函數(shù)multiThree,它接收三個Int型參數(shù)返回它們的乘積:
multiThree :: Int -> Int -> Int -> Int
multiThree x y z = x * y * z
當(dāng)我們將multiThree其中一個參數(shù)固定后,它就變成了一個二參函數(shù)。
ghci > let multiTwoWithNine = multiThree 9
ghci > multiTwoWithNine 2 3
我們使用using關(guān)鍵字實現(xiàn)元函數(shù)轉(zhuǎn)發(fā),可以達(dá)到類似函數(shù)柯里化的效果。柯里化可以幫助更容易地復(fù)用函數(shù),實現(xiàn)函數(shù)之間更低成本且更靈活的組合。
函數(shù)柯里化在函數(shù)式編程語言里的意義非常重要,和C++模板元編程里面的還是有區(qū)別的。例如在Haskell中,可以不用為柯里化函數(shù)定義別名,就直接將其作為另一個函數(shù)的參數(shù)傳遞,而在C++模板元編程里目前還做不到。
現(xiàn)在借助柯里化,我們重新實現(xiàn)Pointer2Of如下:
template<typename T> using Pointer2Of = Times<2, T, PointerOf>;
可以看到,所謂的Pointer2Of,其實就是把Times的第一個和第三個參數(shù)固定后,得到的單參柯里化函數(shù)。