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


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

template<int N>
struct CharPointer
{
    using Result = typename Times<N, char, PointerOf>::Result;
};

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

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

template<int N>
struct CharPointer :Times<N, char, PointerOf>
{
};

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

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

template<int N> using CharPointer = Times<N, char, PointerOf>;

这里我们直接对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<typename T> using Pointer2Of = Times<2, T, PointerOf>;

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


一切都是类型

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容