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

 template <int N>
struct Factorial
{
enum
{
value = N * Factorial<N - >::value
};
}; // 特化版本
template <>
struct Factorial<>
{
enum
{
value =
};
}; int main()
{
cout << Factorial<>::value << endl; // 输出120
}

在编译期,Factorial<5>::value就被翻译成了5 * 4 * 3 * 2 * 1,在运行期直接执行乘法即可。

元编程有何优点?

1. 以编译耗时为代价换来卓越的运行期性能,因为对于产品级的程序而言,运行的时长远大于编译时长。

2. 将原来运行期才能发现的错误提前到了编译期,要知道,错误发现的越早,代价越小。

元编程有何缺点?

1. 代码可读性差,写起来要运用递归的思维,非常困难。

2. 调试困难,元程序执行于编译期,不能debug,只能观察编译器输出的error来定位错误。

3. 编译时间长,运行期的代价转嫁到编译期。

4. 可移植性较差,老的编译器几乎不支持模板或者支持极为有限。

模板元编程TMP虽然有这么多的缺点,但它已经被证明是“图灵完全”的了,意思是它的威力大到足以计算任何事物。目前boost库中用到了一些TMP技术,但大部分项目还是因为TMP的一些缺点而没有广泛采用,所以这里我们只要略做了解即可。

下面总结一下:

1. TMP可将工作由运行期转移到编译期,因而得以实现早期错误侦测或者更高的执行效率。

2. TMP可被用来生成“基于政策选择组合”的客户定制代码,也可以用来避免生成对某些特殊类型并不适合的代码。(这句话看不懂也没关系)

读书笔记_Effective_C++_条款四十八:了解模板元编程的更多相关文章

  1. 读书笔记_Effective_C++_条款四十九:了解new_handler的行为

    本章开始讨论内存分配的一些用法,C/C++内存分配采用new和delete.在new申请内存时,可能会遇到的一种情况就是,内存不够了,这时候会抛出out of memory的异常.有的时候,我们希望能 ...

  2. 读书笔记_Effective_C++_条款四十六:需要类型转换时请为模板定义非成员函数

    这个条款可以看成是条款24的续集,我们先简单回顾一下条款24,它说了为什么类似于operator *这样的重载运算符要定义成非成员函数(是为了保证混合乘法2*SomeRational或者SomeRat ...

  3. 读书笔记_Effective_C++_条款四十五:运用成员函数模板接受所有兼容类型

    比如有一个Base类和一个Derived类,像下面这样: class BaseClass {…}; class DerivedClass : public BaseClass {…}; 因为是父类与子 ...

  4. 读书笔记_Effective_C++_条款二十八:避免返回handlers指向对象内部成分

    举个例子: class Student { private: int ID; string name; public: string& GetName() { return name; } } ...

  5. 读书笔记_Effective_C++_条款四十四:将与参数无关的代码抽离template

    标题上说“将与参数无关的代码抽离template”,这里的参数既可以指类型,也可以是非类型,我们先来看看非类型的情况. 假定我们要为矩阵写一个类,这个矩阵的行列元素个数相等,是一个方阵,因而我们可以对 ...

  6. 读书笔记_Effective_C++_条款四十二:了解typename的双重意义

    顾名思义,typename有双重含意.只要你用过template,那么第一重含意一定知道,那就是声明模板的时候,我们既可以这样写: template <class T> 也可以这样写 te ...

  7. 读书笔记_Effective_C++_条款四十:明智而审慎地使用多重继承

    多重继承是一种比较复杂的继承关系,它意味着如果用户想要使用这个类,那么就要对它的父类也了如指掌,所以在项目中会带来可读性的问题,一般我们都会尽量选择用单继承去替代它. 使用多重继承过程容易碰到的问题就 ...

  8. 读书笔记_Effective_C++_条款三十八:通过复合塑模出has-a或者is-implemented-in-terms-of

    如果说public是一种is-a的关系的话,那么复合就是has-a的关系.直观来说,复合就是在一个类中采用其他类的对象作为自身的成员变量,可以举个例子,像下面这样: class Person { pr ...

  9. 读书笔记_Effective_C++_条款三十:了解inline的里里外外

    学过基本程序课的同学都知道,inline是内联的关键字,它可以建议编译器将函数的每一个调用都用函数本体替换.这是一种以空间换时间的做法.把每一次调用都用本体替换,无疑会使代码膨胀,但可以节省函数调用的 ...

随机推荐

  1. 使用Swift代码演示Cocoa框架

    通过使用简单的代码学习Cocoa框架,每一个例子都通过代码和StoryBoard实现,并且总结他们的各自特点 所有完整代码将会托管到github库,https://github.com/land-pa ...

  2. jQuery获取浏览器URL链接的值

    代码: 方法一: $.extend({ getUrlVars: function () { var vars = [], hash; ).split('&'); ; i < hashes ...

  3. Singleton模式和Mono-State模式

    类和实例 对于大多数的类,都可以创建多个实例.在需要和不需要时,创建和删除这些实例.该过程会伴随着内存的分配和归还. 同时,有一些类,应该仅有一个实例.该实例在程序启动/结束时被创建和删除. root ...

  4. 用自己的算法实现startsWith和endsWith功能

    package hanqi; import java.util.Random; import java.util.Scanner; public class zuoye { public static ...

  5. 如何向Openstack社区提交一个新项目

    前几天有个朋友问我:自己有一个idea不错的项目,也把基本的框架写好了,想贡献到Openstack社区,却不知道应该怎么做.正好之前我有过类似的经历,那么来分享一下我是如何向Openstack社区提交 ...

  6. shell变量注意事项

    概念:变量赋值,变量替换,变量引用,命令替换 variable=22 echo variable 可以在同一行设置多个变量.例如 va1=good   va2=chif va3=beijing  #需 ...

  7. [Aaronyang] 写给自己的WPF4.5 笔记23 [3d交互与动画 4/4]

    效果图预览: 1. 3d中的命中测试 我新建了一个空的窗口,用zam做了一个长方体,深度很小.然后导出xaml <Viewport3D x:Name="ZAM3DViewport3D& ...

  8. 互联网的寒冬来了,BAT都不社招了

    一 总理上次来到创业街,是四个月,要不就是五个月前了. 之后,全国创业形势一路走红,锣鼓喧天鞭炮齐鸣.大众创业万众创新,颇有大炼钢铁亩产万斤之势,尤其在媒体上. 再之后,2015 进入下半年,风投圈的 ...

  9. IE6实现图片或背景的圆角效果

    使用ie-css3.htc实现背景圆角效果 <!DOCTYPE html> <html> <head> <meta http-equiv="Cont ...

  10. CSS层叠样式表的层叠是什么意思(转自知乎)

    转自知乎上的回答:http://www.zhihu.com/question/20077745 解答一: 层叠指的是样式的优先级,当产生冲突时以优先级高的为准.1. 开发者样式>读者样式> ...