初识c++模板元编程
模板元编程(Template metaprogramming,简称TMP)是编译器内执行的程序,编译器读入template,编译输出的结果再与其他源码一起经过普通编译过程生成目标文件。通俗来说,普通运行程序是编译器生成的机器码,由处理器解释执行得到结果,TMP则是编译器实例化template过程中得到结果。TMP已被证明是图灵完备的机器,不过模板实例化通常需要消耗巨大的编译器资源,而且难以追踪错误,没有合适的调试器,所以在实际开发中很少使用。
TMP有两个重要的作用:
- 将工作从运行期转移到编译期,一些在运行期才能发现的错误在编译时就找出来了。
- 产生较小的可执行文件,较短的运行时间,较少的内存需求。当然代价就是增加了编译时间。
下面让我们来看一个利用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++模板元编程的更多相关文章
- 初识C++模板元编程(Template Mega Programming)
前言:毕设时在开源库上做的程序,但是源码看得很晕(当时导师告诉我这是模板元编程,可以不用太在乎),最近自己造轮子时想学习STL的源码,但也是一样的感觉,大致了解他这么做要干什么,但是不知道里面的机制. ...
- C++模板元编程(C++ template metaprogramming)
实验平台:Win7,VS2013 Community,GCC 4.8.3(在线版) 所谓元编程就是编写直接生成或操纵程序的程序,C++ 模板给 C++ 语言提供了元编程的能力,模板使 C++ 编程变得 ...
- C++模板元编程 - 函数重载决议选择工具(不知道起什么好名)完成
这个还是基于之前实现的那个MultiState,为了实现三种类型“大类”的函数重载决议:所有整数.所有浮点数.字符串,分别将这三种“大类”的数据分配到对应的Converter上. 为此实现了一些方便的 ...
- C++模板元编程 - 挖新坑的时候探索到了模板元编程的新玩法
C++真是一门自由的语言,虽然糖没有C#那么多,但是你想要怎么写,想要实现什么,想要用某种编程范式或者语言特性,它都会提供. 开大数运算类的新坑的时候(又是坑),无意中需要解决一个需求:大数类需要分别 ...
- 读书笔记_Effective_C++_条款四十八:了解模板元编程
作为模板部分的结束节,本条款谈到了模板元编程,元编程本质上就是将运行期的代价转移到编译期,它利用template编译生成C++源码,举下面阶乘例子: template <int N> st ...
- c++ 模板元编程的一点体会
趁着国庆长假快速翻了一遍传说中的.大名鼎鼎的 modern c++ design,钛合金狗眼顿时不保,已深深被其中各种模板奇技淫巧伤了身...论语言方面的深度,我看过的 c++ 书里大概只有 insi ...
- C++模板元编程 - 3 逻辑结构,递归,一点列表的零碎,一点SFINAE
本来想把scanr,foldr什么的都写了的,一想太麻烦了,就算了,模板元编程差不多也该结束了,离开学还有10天,之前几天部门还要纳新什么的,写不了几天代码了,所以赶紧把这个结束掉,明天继续抄轮子叔的 ...
- C++模板元编程 - 2 模仿haskell的列表以及相关操作
这是昨天和今天写的东西,利用C++的可变模板参数包以及包展开,模式匹配的一些东西做的,感觉用typename...比轮子叔那个List<A,List<B, List<C, D> ...
- 一道模板元编程题源码解答(replace_type)
今天有一同学在群上聊到一个比较好玩的题目(本人看书不多,后面才知是<C++模板元编程>第二章里面的一道习题), 我也抱着试一试的态度去完成它, 这道题也体现了c++模板元编程的基础和精髓: ...
随机推荐
- Codeforces Round #533 (Div. 2) C. Ayoub and Lost Array 【dp】
传送门:http://codeforces.com/contest/1105/problem/C C. Ayoub and Lost Array time limit per test 1 secon ...
- git的一些小命令
git_cmd git常用命令 <>代表变量,例如 代表分支名称 远程库 查看远程库信息 git remote -v 查看远程仓库:$ git remote -v 添加远程仓库:$ git ...
- iOS开发中方法延迟执行的几种方式
概述 项目开发中经常会用到方法的延时调用,下面列举常用的几种实现方式: 1.performSelector 2.NSTimer 3.NSThread线程的sleep 4.GCD 1.performSe ...
- 二. Python WebDriver环境搭建
1. 安装Selenium 在命令行中输入: 显示安装成功: 2. 测试例子 打开百度页面并在输入框输入搜索内容(默认为firework) # 1. Selenium默认为Firefox.验证 fro ...
- hdu 1520 Anniversary party(第一道树形dp)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1520 Anniversary party Time Limit: 2000/1000 MS (Java ...
- css左固定右自适应常用方法
下面是几种方法的公用部分(右自适应也是一样的,换一下方向) html: <div class="demo"> <div class="sidebar&q ...
- iOS获取通讯录所有联系人信息
以下是2种方式: 第一种方法: GetAddressBook.h #import <Foundation/Foundation.h> @interface GetAddressBook : ...
- chromium之dynamic_annotations
看看介绍 // This file defines dynamic annotations for use with dynamic analysis // tool such as valgrind ...
- CentOS 6.8安装Ceph
机器规划 IP 主机名 角色 10.101.0.1 ceph01 mon admin mds 10.101.0.2 ceph02 ods 10.101.0.3 ceph03 ods 10.101.0. ...
- keepalived+haproxy 安装配置
1.安装配置keepalived 修改配置文件/etc/keepalived/keepalived.conf ! Configuration File for keepalived global_de ...