C++模板元编程 入门简介
最近一直在看STL和Boost,源码里边好多涉及到模板元编程技术,简单了解一下,备忘(Boost Python中的涉及模板元的部分重点关注一下)。
范例引入
// 主模板 template<int N> struct Fib {enum { Result = Fib<N-1>::Result + Fib<N-2>::Result }; };// 完全特化版 template <> struct Fib<1> {enum { Result = 1 }; };// 完全特化版 template <> struct Fib<0> {enum { Result = 0 }; };int main() {int i = Fib<10>::Result;// std::cout << i << std::endl; }
主要思想
利用模板特化机制实现编译期条件选择结构,利用递归模板实现编译期循环结构,模板元程序则由编译器在编译期解释执行。
优劣及适用情况
通过将计算从运行期转移至编译期,在结果程序启动之前做尽可能多的工作,最终获得速度更快的程序。也就是说模板元编程的优势在于:
1.以编译耗时为代价换来卓越的运行期性能(一般用于为性能要求严格的数值计算换取更高的性能)。通常来说,一个有意义的程序的运行次数(或服役时间)总是远远超过编译次数(或编译时间)。
2.提供编译期类型计算,通常这才是模板元编程大放异彩的地方。
模板元编程技术并非都是优点:
1.代码可读性差,以类模板的方式描述算法也许有点抽象。
2.调试困难,元程序执行于编译期,没有用于单步跟踪元程序执行的调试器(用于设置断点、察看数据等)。程序员可做的只能是等待编译过程失败,然后人工破译编译器倾泻到屏幕上的错误信息。
3.编译时间长,通常带有模板元程序的程序生成的代码尺寸要比普通程序的大,
4.可移植性较差,对于模板元编程使用的高级模板特性,不同的编译器的支持度不同。
总结:
模板元编程技术不适用普通程序员的日常应用,它常常会做为类库开发的提供技术支持,为常规模板代码的内核的关键算法实现更好的性能或者编译期类型计算。模板元程序几乎总是应该与常规代码结合使用被封装在一个程序库的内部。对于库的用户来说,它应该是透明的。
工程应用实例
1. Blitz++:由于模板元编程最先是因为数值计算而被发现的,因此早期的研究工作主要集中于数值计算方面,Blitz++库利用模板将运行期计算转移至编译期的库,主要提供了对向量、矩阵等进行处理的线性代数计算。
2.Loki:将模板元编程在类型计算方面的威力应用于设计模式领域,利用元编程(以及其他一些重要的设计技术)实现了一些常见的设计模式之泛型版本。Loki库中的Abstract Factory泛型模式即借助于这种机制实现在不损失类型安全性的前提下降低对类型的静态依赖性。
3.Boost:元编程库目前主要包含MPL、Type Traits和Static Assert等库。 Static Assert和Type Traits用作MPL的基础。Boost Type Traits库包含一系列traits类,用于萃取C++类型特征。另外还包含了一些转换traits(例如移除一个类型的const修饰符等)。Boost Static Assert库用于编译期断言,如果评估的表达式编译时计算结果为true,则代码可以通过编译,否则编译报错。
技术细节
模板元编程使用静态C++语言成分,编程风格类似于函数式编程,在模板元编程中,主要操作整型(包括布尔类型、字符类型、整数类型)常量和类型,不可以使用变量、赋值语句和迭代结构等。被操纵的实体也称为元数据(Metadata),所有元数据均可作为模板参数。
由于在模板元编程中不可以使用变量,我们只能使用typedef名字和整型常量。它们分别采用一个类型和整数值进行初始化,之后不能再赋予新的类型或数值。如果需要新的类型或数值,必须引入新的typedef名字或常量。
其它范例
// 仅声明 struct Nil;// 主模板 template <typename T> struct IsPointer {enum { Result = false };typedef Nil ValueType; };// 局部特化 template <typename T> struct IsPointer<T*> {enum { Result = true };typedef T ValueType; };// 示例 int main() {cout << IsPointer<int*>::Result << endl;cout << IsPointer<int>::Result << endl;IsPointer<int*>::ValueType i = 1;//IsPointer<int>::ValueType j = 1; // 错误:使用未定义的类型Nil }
//主模板 template<bool> struct StaticAssert;// 完全特化 template<> struct StaticAssert<true> {};// 辅助宏 #define STATIC_ASSERT(exp)\ { StaticAssert<((exp) != 0)> StaticAssertFailed; }int main() {STATIC_ASSERT(0>1); }
References:
http://club.topsage.com/thread-421469-1-1.html
http://wenku.baidu.com/view/c769720df78a6529647d539d.html
Blitz++: http://www.oonumerics.org/blitz .
Loki :http://sourceforge.net/projects/loki-lib
Boost:http://www.boost.org/
转载于:https://www.cnblogs.com/salomon/archive/2012/06/04/2534787.html
C++模板元编程 入门简介相关推荐
- C++ 模板元编程简介
文章目录 1.概述 2.模板元编程的作用 3.模板元编程的组成要素 4.模板元编程的控制逻辑 4.1 if 判断 4.2 循环展开 4.3 switch/case 分支 5.特性.策略与标签 6.小结 ...
- 基于C++11模板元编程实现Scheme中的list及相关函数式编程接口
前言 本文将介绍如何使用C++11模板元编程实现Scheme中的list及相关函数式编程接口,如list,cons,car,cdr,length,is_empty,reverse,append,map ...
- 【C++ 泛型编程 进阶篇】:用std::integral_constant和std::is_*系列深入理解模板元编程
C++ 元模版编程:用std::integral_constant和std::is_*系列深入理解模板元编程 一.模板元编程与类型特性 (Template Metaprogramming and Ty ...
- 模板元编程实现素数判定
模板元编程(英语:Template metaprogramming:缩写:TMP)是一种元编程技术,不夸张的说,这项技术开启了一种新的C++编程方式.编译器使用模板产生暂时性的源码,然后再和剩下的源码 ...
- 编程实现算术表达式求值_用魔法打败魔法:C++模板元编程实现的scheme元循环求值器...
本文使用 Zhihu On VSCode 创作并发布 [TOC] 前言 寒假时沉迷C++模板元编程,写了个简单的Scheme元循环求值器.可以用类似Scheme的语法写出这样的C++模板代码: _&l ...
- C++用模板元编程进行循环展开的性能测试
在网上看到一篇C++模板元编程的文章,里面提到可以用来做循环展开,文章地址如下: https://www.2cto.com/kf/20120... 然后在VS2015里测了一下,测试代码如下: tem ...
- xpath里面if判断一个值不为空_现代C++之模板元编程(今天写个If与While)
现代C++之模板元编程(今天写个If与While) 0.导语 今天就放轻松,有可能代码写的看的很晦涩,自己多敲几遍即可,下面来进入正文,如何使用模板元编程实现IF与WHILE. 1.IF实现 我们想要 ...
- 现代C++模板元编程基础
元函数的基础介绍 C++的模板元编程是函数式编程,所以函数是一等公民.一切在编译期间执行的函数都可以称为元函数.元函数有struct和constexpr两种定义方式,前者是一直使用的,后者是C++11 ...
- 跟我学c++高级篇——模板元编程之十一鸭子类型
一.鸭子类型 鸭子类型不是从c++中出现的,duck typing这种称呼在Python中比较多见.那么什么是鸭子类型呢?它是动态类型的一种风格,只要是对象的特征(其方法和属性集)和某个类型一致,就认 ...
最新文章
- 推荐系统算法_机器学习和推荐系统(二)推荐算法简介
- svn 迁移到 git 仓库并保留 commit 历史记录
- HDU - 2871 Memory Control(线段树+区间合并)好题!
- att汇编教程 linux,ATT 汇编语法
- V210 系统时间设置
- 嵌入式入门之烧录操作系统
- hdu 1026【Ignatius and the Princess I】
- CAD梦想画图中的“离散曲线命令”
- 《软件工程与实践》 |(一)软件工程基础概述 知识梳理
- 博途编程语言切换_从一种编程语言切换到另一种:灵活的好处
- 利用Word2Vec在语料中构建种子词集同类词
- Liang-Barsky算法思想及简单cpp实现
- iSCSI Target和Initiator安装与操作步骤详解
- Ubuntu18.04安装坚果云
- mac+微信打开连接到服务器,MAC OS系统 ,微信接收到的文件,打开wo… - Apple 社区...
- 电脑有网但打不开网页怎么办?
- 前端解决web端 125%,150%缩放,1366*768分辨率兼容问题
- springboot2.4开启HTTPS功能报DerInputStream.getLength(): lengthTag=111, too big异常
- raid管理软件MegaRAID Storage Manager(MSM)的安装和使用
- 经典文献阅读之--Cam2BEV