C++11 模板元编程 - 柯理函数


现在,我们想实现一个元函数,可以返回char类型指定层数的指针类型。

template
struct CharPointer
{
    using Result = typename Times::Result;
};

如上,我们定义了元函数CharPointer,它是一个int型单参元函数。它的实现调用了Times,将其第二和第三个参数分别固定为char和PointerOf。

借助于继承的特性,上面的代码可以简化为:

template
struct CharPointer :Times
{
};

这种定义元函数的方式叫做元函数转发

如果借助using关键字,可以实现得更加简单:

template using CharPointer = Times;

这里我们直接对Times绑定第二和第三个参数后为其起了别名CharPointer。

在函数式编程里面,有个概念叫做函数柯里化(currying),是指一个函数接收部分参数后,并不立即求值,而是继续返回另一个函数。

如下Haskell代码定义了一个三数相乘的函数multiThree,它接收三个Int型参数返回它们的乘积:

multiThree :: Int -> Int -> Int -> Int
multiThree x y z = x * y * z

当我们将multiThree其中一个参数固定后,它就变成了一个二参函数。

ghci > let multiTwoWithNine = multiThree 9
ghci > multiTwoWithNine 2 3

我们使用using关键字实现元函数转发,可以达到类似函数柯里化的效果。柯里化可以帮助更容易地复用函数,实现函数之间更低成本且更灵活的组合。

函数柯里化在函数式编程语言里的意义非常重要,和C++模板元编程里面的还是有区别的。例如在Haskell中,可以不用为柯里化函数定义别名,就直接将其作为另一个函数的参数传递,而在C++模板元编程里目前还做不到。

现在借助柯里化,我们重新实现Pointer2Of如下:

template using Pointer2Of = Times<2, T, PointerOf>;

可以看到,所谓的Pointer2Of,其实就是把Times的第一个和第三个参数固定后,得到的单参柯里化函数。


一切都是类型

返回 C++11模板元编程 - 目录

你可能感兴趣的:(C++11 模板元编程 - 柯理函数)