美文网首页
C++11 模板元编程 - 元函数

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

作者: MagicBowen | 来源:发表于2016-09-15 09:10 被阅读1672次

我们继续演进前面那个无聊的类型计算的例子,来得出元函数的定义。

前面我们实现了PointerOf,它对于传进的任意类型T可以计算出T的指针类型。

template<typename T>
struct PointerOf
{
    using Result = T*;
};

现在我们想要实现一个能够计算T的指针的指针类型的模板,怎么做?

一种做法是直接定义一个新的模板:

template<typename T>
struct Pointer2Of
{
    using Result = T**;
};

为了让类型计算结果更像是出自函数的返回值,我们将计算结果的类型别名后续统一叫做Result。上述类模板本质上是一个对类型进行计算的函数:

Pointer2Of :: (typename T) => T -> T**

可以这样使用该函数:

int* pi;
Pointer2Of<int>::Result ppi = &pi

上述代码中Pointer2Of<int>::Result的计算发生在编译期,当在C++运行期前它已经得到计算结果int**了。所以上述代码在编译器计算完成后,就相当于如下代码:

int* pi;
int** ppi = &pi

虽然我们把类模板当做编译期函数来看,但是这种函数语法看起来和我们熟悉的函数相差较大,但究其本质和函数调用并无差异,都是为函数传入符合要求的实参,获得函数返回结果。

我们可以认为由于圆括号已经优先给了运行时C++函数,所以这种编译期C++函数的定义和调用都使用尖括号,并且需要显示调用Result才对函数进行运算求值。当使用这种编译期函数但并不调用Result时,和在“运行期C++”中使用一个函数指针类似,仅用做保存和传递用,但并不求值。

编译期函数计算,可以调用已有的其它编译期函数。如下通过嵌套调用PointerOf,也可以实现Pointer2Of:

template<typename T>
struct Pointer2Of
{
    using Result = typename PointerOf<typename PointerOf<T>::Result>::Result;
};

上面我们通过嵌套调用两次PointerOf来完成Pointer2Of的实现。在Pointer2Of中我们每次使用PointerOf<...>::Result时前面都用了typename关键字。原因是一旦PointerOf后面的尖括号中存在非具体类型的话,那么PointerOf的内部类型Result就是一个推导类型。C++标准要求使用推导类型前面必须使用typename关键字显示指明这是一个类型。所以我们在Pointer2Of中使用PointerOf完整的方式是这样的:typename PointerOf<...>::Result

和Haskell相比,我们必须得承认C++的这种函数式编程的书写确实太繁琐了。为了简化对元函数的使用,我们可以用宏封装一下PointerOf:

#define __pointer(...) typename PointerOf<__VA_ARGS__>::Result

这样Pointer2Of的定义可以简化如下:

template<typename T>
struct Pointer2Of
{
    using Result = __pointer(__pointer(T));
};

现在看起来好多了,__pointer(T)的写法更像是在调用一个函数。

可以看到我们对类模板进行约束,固定用Result保存计算结果,且只返回单一结果,可以使我们将模板当做函数使用时的写法得到统一,这对于我们进行函数组合简直是必须的。

后续我们将一直把这种在编译期进行计算,靠Result返回计算结果的类模板看作是编译期的函数,它的目的是为了支持C++模板元编程。为了和C++运行时函数进行区分,后文中我们统一将其称作元函数

如同函数是函数式编程的构成基础一样,元函数是C++模板元编程的构成基础。


高阶函数

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

相关文章

  • C++11 模板元编程 - 元函数

    我们继续演进前面那个无聊的类型计算的例子,来得出元函数的定义。 前面我们实现了PointerOf,它对于传进的任意...

  • C++11 模板元编程 - 两阶段的C++语言

    前面我们介绍了C++模板元编程的基础知识。我们将模板元编程的计算对象统一到类型上,引入了元函数的概念。元函数是模板...

  • C++11 模板元编程 - 元函数转发

    前面介绍了元函数转发的概念,也就是通过已有的元函数组合,来定义新的元函数。 如下我们实现一个元函数TypeSize...

  • 模板元编程

    什么是模板元 模板元编程是一种编译期计算的编程方法。如果你学过任意一门函数式的编程语言,那么你对模板元编程的理解一...

  • C++11 模板元编程 - 元编程

    从本节开始我们将模板元编程当做一门独立的函数式语言来讨论它的方方面面。 所谓元编程,就是指可以产生程序的程序。由于...

  • C++11 模板元编程 - 高阶函数

    接着上面的例子,此刻我们想要定义指向指针的指针的指针的指针类型,怎么办?或者说我们想要一种能够任意指定指针层数的元...

  • C++11 模板元编程 - 基础类型和元函数

    前面已经介绍过了,TLP库中通过IntType和BoolType对int和bool值进行封装,并且提供了对应的计算...

  • C++11 模板元编程 - 模板元编程的应用

    本节开始我们通过使用C++模板元编程去解决一些实际问题,来展示模板元编程针对现实问题的使用方法和设计技巧。本节中的...

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

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

  • 14/15

    约束模板友元 模板类的外边定义一个模板函数,在模板类中将模板函数具体化为模板类的友元函数 非约束模板友元 模板类中...

网友评论

      本文标题:C++11 模板元编程 - 元函数

      本文链接:https://www.haomeiwen.com/subject/irlbettx.html