C++模板元编程实战:一个深度学习框架的初步实现 - (EPUB全文下载)

文件大小:0.29 mb。
文件格式:epub 格式。
书籍内容:

C++模板元编程实战:一个深度学习框架的初步实现
第一部分 元编程基础技术
第1章 基本技巧
第2章 异类词典与policy模板
第3章 深度学习概述
第4章 类型体系与基本数据类型
第5章 运算与表达式模板
第6章 基本层
第7章 复合层与循环层
第8章 求值与优化
后记——方家休见笑,吾道本艰难
第一部分  元编程基础技术
第1章 基本技巧
本章将讨论元编程与编译期计算所涉及的基本方法。我们首先介绍元函数,通过简单的示例介绍编译期与运行期所使用“函数”的异同。其次,在此基础上进一步讨论基本的顺序、分支、循环代码的书写方式。最后介绍一种经典的技巧——奇特的递归模板式。
上述内容可以视为基本的元编程技术。而本书后续章节也可以视为这些技术的应用。掌握好本章所讨论的技术,是熟练使用C++模板元编程与编译期计算的前提。
1.1 元函数与type_traits
1.1.1 元函数介绍
C++元编程是一种典型的函数式编程,函数在整个编程体系中处于核心的地位。这里的函数与一般C++程序中定义与使用的函数有所区别,更接近数学意义上的函数——是无副作用的映射或变换:在输入相同的前提下,多次调用同一个函数,得到的结果也是相同的。
如果函数存在副作用,那么通常是由于存在某些维护了系统状态的变量而导致的。每次函数调用时,即使输入相同,但系统状态的差异会导致函数输出结果不同:这样的函数被称为具有副作用的函数。元函数会在编译期被调用与执行。在编译阶段,编译器只能构造常量作为其中间结果,无法构造并维护可以记录系统状态并随之改变的量,因此编译期可以使用的函数(即元函数)只能是无副作用的函数。
以下代码定义了一个函数,满足无副作用的限制,可以作为元函数使用。
1 constexpr int fun(int a) { return a + 1; }
其中的constexpr为C++ 11中的关键字,表明这个函数可以在编译期被调用,是一个元函数。如果去掉了这个关键字,那么函数fun将只能用于运行期,虽然它具有无副作用的性质,但也无法在编译期被调用。
作为一个反例,考虑如下的程序:
1 static int call_count = 3;
2 constexpr int fun2(int a)
3 {
4 return a + (call_count++);
5 }
这个程序片断无法通过编译——它是错误的。原因是函数内部的逻辑丧失了“无副作用”的性质——相同输入会产生不同的输出;而关键字constexpr则试图保持函数的“无副作用”特性,这就导致了冲突。将其进行编译会产生相应的编译错误。如果将函数中声明的constexpr关键字去掉,那么程序是可以通过编译的,但fun2无法在编译期被调用,因为它不再是一个元函数了。
希望上面的例子能让读者对元函数有一个基本的印象。在C++中,我们使用关键字constexpr来表示数值元函数,这是C++中涉及的一种元函数,但远非全部。事实上,C++中用得更多的是类型元函数——即以类型作为输入和(或)输出的元函数。
1.1.2 类型元函数
从数学角度来看,函数通常可以被写为如下的形式:
其中的3个符号分别表示了输入(x)、输出(y)与映射(f)[1]。通常来说,函数的输入与输出均是数值。但我们大可不必局限于此:比如在概率论中就存在从事件到概率值的函数映射,相应的输入是某个事件描述,并不一定要表示为数值。
回到元编程的讨论中,元编程的核心是元函数,元函数输入、输出的形式也可以有很多种,数值是其中的一种,由此衍生出来的就是上一节所提到的数值元函数;也可以将C++中的数据类型作为函数的输入与输出。考虑如下情形:我们希望将某个整数类型映射为相应的无符号类型。比如,输入类型int时,映射结果为unsigned int;而输入为unsigned long时,我们希望映射的结果与输入相同。这种映射也可以被视作函数,只不过函数的输入是int、unsigned long等类型,输出是另外的一些类型而已。
可以使用如下代码来实现上述元函数:
1 template
2 struct Fun_ { using type = T; };
3
4 template <>
5 struct Fun_ { using type = unsigned int; };
6
7 template <>
8 struct Fun_ { using type = unsigned long; };
9
10 Fun_::type h = 3;
读者可能会问:函数定义在哪儿?最初接触元函数的读者往往会有这样的疑问。事实上,上述片断的1~8行已经定义了一个函数Fun_第10行则使用了这个Fun_::type函数返回unsigned int,所以第10行相当于定义了一个无符号整型的变量h并赋予值3。
Fun_与C++一般意义上的函数看起来完全不同,但根据前文对函数的定义,不难发现,Fun_具备了一个元函数所需要的全部性质:
输入为某个类型信息T,以模板参数的形式传递到Fun_模板中;
输出为Fun_模板的内部类型type,即Fun_::type;
映射体现为模板通过特化实现的转换逻辑:若输入类型为int,则输出类型为unsigned int,等等。
在C++ 11发布之前,已经有一些讨论C++元函数的著作了。在《C++模板元编程》一书[2]中,将上述程序段中的1~6行所声明的Fun_视为元函数:认为函数输入是X时,输出为Fun_::type。同时,该书规定了所讨论的元函数的输入与输出均是类型。将一个包含了type声明的类模板称为元函数,这一点并无不妥之处:它完全满足元函数无副作用的要求。但作者认为,这种定义还是过于狭隘了。当然像这样引入限制,相当于在 ............

以上为书籍内容预览,如需阅读全文内容请下载EPUB源文件,祝您阅读愉快。

版权声明:书云(openelib.org)是世界上最大的在线非盈利图书馆之一,致力于让每个人都能便捷地了解我们的文明。我们尊重著作者的知识产权,如您认为书云侵犯了您的合法权益,请参考版权保护声明,通过邮件openelib@outlook.com联系我们,我们将及时处理您的合理请求。 数研咨询 流芳阁 研报之家 AI应用导航 研报之家
书云 Open E-Library » C++模板元编程实战:一个深度学习框架的初步实现 - (EPUB全文下载)