模板元编程(Template metaprogramming,简称TMP)是编译器内执行的程序,编译器读入template,编译输出的结果再与其他源码一起经过普通编译过程生成目标文件。通俗来说,普通运行程序是编译器生成的机器码,由处理器解释执行得到结果,TMP则是编译器实例化template过程中得到结果。TMP已被证明是图灵完备的机器,不过模板实例化通常需要消耗巨大的编译器资源,而且难以追踪错误,没有合适的调试器,所以在实际开发中很少使用。

TMP有两个重要的作用:

  1. 将工作从运行期转移到编译期,一些在运行期才能发现的错误在编译时就找出来了。
  2. 产生较小的可执行文件,较短的运行时间,较少的内存需求。当然代价就是增加了编译时间。

下面让我们来看一个利用TMP计算3的幂的例子

template<int N>
class Pow3 {
public:
enum {result=*Pow3<N->::result};
}; template<>
class Pow3<> {
public:
enum {result=};
}; int main() {
std::cout<<"Pow3<7> = "<<Pow3<>::result<<std::endl;
}

Pow<7>的实例化导致Pow3<6>的实例化,Pow3<6>又出发Pow3<5>的实例化,递归直至Pow3<0>结束,Pow<7>::result直接被常量值替换。

一个TMP程序可以包含以下几部分:

  • 状态变量:即模板参数
  • 迭代构造:TMP没有循环等构件,全部用递归实现,另一方面递归的实例化也是降低编译器效率的主要原因。
  • 路径选择:通过使用条件表达式或者特化。
  • 整形算法(即枚举)

c++中,在类内部声明常量值只有枚举和静态常量初始化两种方式。上面的例子中可以将枚举改成静态常量,

template<int N>
class Pow3 {
public:
static int const result=*Pow3<N->::result;
}; template<>
class Pow3<> {
public:
static int const result=;
};

不过静态常量是左值,如果将结果作为引用参数传递给一个函数,

void foo(int const&);

foo(Pow3<7>::result);

编译器必须获取 Pow3<7>::result的地址,这会强制编译器实例化静态成员的定义,并分配内存,这就跳出了编译期范围。

而枚举不是左值,没有这个约束,通过引用传递的时候跟使用常量值形式是一样的,所以一般都用枚举类型。

Reference:

《c++ templates: the complete guide》

《effective c++》

初识c++模板元编程的更多相关文章

  1. 初识C++模板元编程(Template Mega Programming)

    前言:毕设时在开源库上做的程序,但是源码看得很晕(当时导师告诉我这是模板元编程,可以不用太在乎),最近自己造轮子时想学习STL的源码,但也是一样的感觉,大致了解他这么做要干什么,但是不知道里面的机制. ...

  2. C++模板元编程(C++ template metaprogramming)

    实验平台:Win7,VS2013 Community,GCC 4.8.3(在线版) 所谓元编程就是编写直接生成或操纵程序的程序,C++ 模板给 C++ 语言提供了元编程的能力,模板使 C++ 编程变得 ...

  3. C++模板元编程 - 函数重载决议选择工具(不知道起什么好名)完成

    这个还是基于之前实现的那个MultiState,为了实现三种类型“大类”的函数重载决议:所有整数.所有浮点数.字符串,分别将这三种“大类”的数据分配到对应的Converter上. 为此实现了一些方便的 ...

  4. C++模板元编程 - 挖新坑的时候探索到了模板元编程的新玩法

    C++真是一门自由的语言,虽然糖没有C#那么多,但是你想要怎么写,想要实现什么,想要用某种编程范式或者语言特性,它都会提供. 开大数运算类的新坑的时候(又是坑),无意中需要解决一个需求:大数类需要分别 ...

  5. 读书笔记_Effective_C++_条款四十八:了解模板元编程

    作为模板部分的结束节,本条款谈到了模板元编程,元编程本质上就是将运行期的代价转移到编译期,它利用template编译生成C++源码,举下面阶乘例子: template <int N> st ...

  6. c++ 模板元编程的一点体会

    趁着国庆长假快速翻了一遍传说中的.大名鼎鼎的 modern c++ design,钛合金狗眼顿时不保,已深深被其中各种模板奇技淫巧伤了身...论语言方面的深度,我看过的 c++ 书里大概只有 insi ...

  7. C++模板元编程 - 3 逻辑结构,递归,一点列表的零碎,一点SFINAE

    本来想把scanr,foldr什么的都写了的,一想太麻烦了,就算了,模板元编程差不多也该结束了,离开学还有10天,之前几天部门还要纳新什么的,写不了几天代码了,所以赶紧把这个结束掉,明天继续抄轮子叔的 ...

  8. C++模板元编程 - 2 模仿haskell的列表以及相关操作

    这是昨天和今天写的东西,利用C++的可变模板参数包以及包展开,模式匹配的一些东西做的,感觉用typename...比轮子叔那个List<A,List<B, List<C, D> ...

  9. 一道模板元编程题源码解答(replace_type)

    今天有一同学在群上聊到一个比较好玩的题目(本人看书不多,后面才知是<C++模板元编程>第二章里面的一道习题), 我也抱着试一试的态度去完成它, 这道题也体现了c++模板元编程的基础和精髓: ...

随机推荐

  1. 5.spring:注解配置 Bean

    在classpath中扫描组件 组键扫描:能够从classpath下自动扫描,侦测和实例化具有特定注解的组件 特定的组件包括: ->@Componment:基于注解,标识一个受Spring管理的 ...

  2. ASP.NET SingalR 点对点聊天实现思路总结

    前一段时间写了一个简单的聊天室,是群聊的方式.博客地址:http://www.cnblogs.com/panzi/p/4980346.html.还有一种需求就是常见的尤其是培训机构的主页面,经常会有1 ...

  3. IP黑白名单

    防攻击可以增加IP白名单/etc/hosts.allow和黑名单/etc/hosts.deny /etc/hosts.allow  IP白名单 /etc/hosts.deny   IP黑名单 /etc ...

  4. centos中java安装跟配置

    安装配置java环境 [root@JxateiLinux src]# Wget  http://download.oracle.com/otn-pub/java/jdk/8u161-b12/2f38c ...

  5. ubuntu software center和新立得

    打开软件库,可以搜索或在终端输入software-center如果没有,可能没有安装软件库,可以在终端安装:sudo apt-get install software-center[注意全部小写]使用 ...

  6. 高性能mysql:创建高性能的索引

    本文系阅读<高性能MySQL>,Baron Schwartz等著一书中第五章 创建高性能的索引的笔记,索引是存储引擎用于快速找到记录的一种数据结构. 索引对于良好的性能非常关键,尤其是当表 ...

  7. NodeJ Koa2 安装使用 reeber

    介绍 Koa 是由 Express 原班人马打造的,致力于成为一个更小.更富有表现力.更健壮的 Web 框架. 使用 koa 编写 web 应用,通过组合不同的 generator,可以免除重复繁琐的 ...

  8. 复习宝典之Spring

    查看更多宝典,请点击<金三银四,你的专属面试宝典> 第六章:Spring Spring容器是Spring的核心,一切Spring bean都存储在Spring容器内,并由其通过IoC技术管 ...

  9. spring-quartz 定时器 给targetMethod传递参数

    今天在做一个项目的时候,要给一个定时器任务的执行方法传递参数,在网上找了一下资料,可以使用arguments参数:   <bean id="subsidyJobDetail" ...

  10. openstack之kvm常用操作

    KVM虚拟机的管理主要是通过virsh命令对虚拟机进行管理. 1.   查看KVM虚拟机配置文件及运行状态 KVM虚拟机默认配置文件位置: /etc/libvirt/qemu/ autostart目录 ...