在C++98/03语言标准中,对于源代码中出现的每一处模板实例化,编译器都需要去做实例化的工作;而在链接时,链接器还需要移除重复的实例化代码。显然,让编译器每次都去进行重复的实例化工作显然是不必要的,并且连接器也因此受累。
在现实编码世界里,一个软件的实现可能会在很多代码块中使用同一种类型去实例化同一个模板。此时,如果能够让编译器避免此类重复的实例化工作,那么可以大大提供编译器的工作效率。因此,人们迫切需要一种手段(一种声明方式)来告诉编译器“该处出现的模板实例化工作已在其它编译单元中完成,不再需要进行实例化”。
于是,一个新的语言特性————外部模板(Extern Template)————被纳入到C++0x标准中。
在C++98/03中,已经有一个叫做显示实例化(Explicit Instantiation)的语言特性,其目的是指示编译器立即进行模板实例化操作(即强制实例化)。而外部模板语法就是在显示实例化指令的语法基础上进行修改得到的:通过在显示实例化指令前添加前缀extern,从而得到外部模板的语法。
显示实例化语法:template class vector<MyClass>;
外部模板语法:extern template class vector<MyClass>;
一旦在一个编译单元中使用了外部模板声明(如extern template class vector<MyClass>;),那么编译器在编译该编译单元时,会跳过与该外部模板声明匹配的模板实例化(如vector<MyClass>)。
因此,在C++0x中,“模板的显示实例化指令、外部模板指令和使用”可以类比为“全局变量的定义、声明和使用”。区别仅在于,模板代表代码,而变量代表一段连续内存空间。
关于外部模板语法的一些约束:
1. 如果外部模板指令出现于一个编译单元中,那么与之对应的显示实例化必须出现于另一个编译单元中或者同一个编译单元的后续代码中。
2. 外部模板指令不能用于一个静态函数(即文件域函数),但可以用于类静态函数。(注:这一点是显而易见的,因为静态函数没有外部连接属性,不可能在本编译单元之外出现)。
3. 外部模板指令应用于类的成员,而不是类本身。(注:既然已经作用于类的所有成员了,也就相当于作用于类了)
4. 外部模板对于内联函数是否有用,没有明确规定,但鼓励编译器实现。
编译器支持
Visual Studio好像是从VS2008(VC9)开始支持外部模板的。GCC似乎很早就支持外部模板了,但不清楚具体是在哪一个版本中加入的,至少4.3及其以后的版本是支持的。
Ref
1. Adding "extern template" (version 2)
2. C++0x,Extern Template @ Wiki

C++11 : 外部模板(Extern Template)的更多相关文章

  1. C++11外部模板

    [C++11之外部模板] 在标准C++中,只要在编译单元内遇到被完整定义的模板,编译器都必须将其实例化(instantiate).这会大大增加编译时间,特别是模板在许多编译单元内使用相同的参数实例化. ...

  2. 编译器对C++ 11变参模板(Variadic Template)的函数包扩展实现的差异

    编译器对C++ 11变参模板(Variadic Template)的函数包扩展实现的差异 题目挺绕口的.C++ 11的好东西不算太多,但变参模板(Variadic Template)肯定是其中耀眼的一 ...

  3. 模板(Template)

    最近阅读google chromium base container stack_container代码,深刻感觉到基础知识不扎实. // Casts the buffer in its right ...

  4. javascript模板库jsrender加载并缓存外部模板文件

    前一篇说了jsrender嵌套循环的使用,在SPA的应用中,广泛使用的一个点就是view模板,使用了SPA之后,每个业务页面不再是独立的html,仅仅是一个segment,所以通常这些segment会 ...

  5. groot 引入外部模板

    index7.html <html><head> <title>groots引入外部模板van</title> <script src=" ...

  6. Django——模板层(template)(模板语法、自定义模板过滤器及标签、模板继承)

    前言:当我们想在页面上给客户端返回一个当前时间,一些初学者可能会很自然的想到用占位符,字符串拼接来达到我们想要的效果,但是这样做会有一个问题,HTML被直接硬编码在 Python代码之中. 1 2 3 ...

  7. Elasticsearch之索引模板index template与索引别名index alias

    为什么需要索引模板? 在实际工作中针对一批大量数据存储的时候需要使用多个索引库,如果手工指定每个索引库的配置信息(settings和mappings)的话就很麻烦了. 所以,这个时候,就存在创建索引模 ...

  8. [ 随手记 4 ]C/C++ 模板(Template)使用/重载区别

    (原创)个人理解: 模板,故名思义,就是一个模子: 模板分为:类模板和函数模板(也可叫模板类和模板函数): 模板特点:(1)函数名字一样: (2)调用的形参的数据类型不同,但形参个数相同: (3)函数 ...

  9. DjangoMTV模型之视图层views及模板层template

    Django视图层中views的内容 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容(render),也可以是一个重定向( ...

随机推荐

  1. 【转】三十分钟学会STL算法

    转载自: http://net.pku.edu.cn/~yhf/UsingSTL.htm 这是本小人书.原名是<using stl>,不知道是谁写的.不过我倒觉得很有趣,所以化了两个晚上把 ...

  2. 关于char与varchar,varchar2的区别

    http://zhidao.baidu.com/question/220360696.html?qbl=relate_question_0&word=char%BA%CDvarchar2%B5 ...

  3. JavaScript 函数作用域和闭包

    函数作用域和闭包  词法作用域   它们在定义它们的作用域里运行,而不是在执行的作用域运行,但是只有在运行时,作用域链中的属性才被 定义(调用对象),此时,可访问任何当前的绑定.   调用对象     ...

  4. 软件测试 homework2

    1. 程序1:   for循环的i>0改为i>=0: 程序2:   for循环for (int i = 0; i < x.length; i++)改为for (int i = x.l ...

  5. [转]C++智能指针的创建

    zero 坐在餐桌前,机械的重复“夹菜 -> 咀嚼 -> 吞咽”的动作序列,脸上用无形的大字写着:我心不在焉.在他的对面坐着 Solmyr ,慢条斯理的吃着他那份午餐,维持着他一贯很有修养 ...

  6. UML中聚合和组合的区别

    聚合 聚合其实是关联的一个特例,表示了两个对象之间“part of(部分-整体)”的关系,是一种弱关联,部分的生命周期可以超越整体.在UML中,用整体端有空心菱形箭头的双向关联修饰聚合.聚合的示例如下 ...

  7. 直接拨号、将电话号码传入拨号程序、调用拨号程序、调用系统浏览器浏览网页、调用系统程序查看联系人、显示系统设置界面和显示Wi-Fi设置界面代码

    直接拨号.将电话号码传入拨号程序.调用拨号程序.调用系统浏览器浏览网页.调用系统程序查看联系人.显示系统设置界面和显示Wi-Fi设置界面代码 拨打号码的代码如下: Intent callIntent= ...

  8. UIScrollView 滚动停止的时候一次调用此方法

    //拖动返回选中的索引 当滚动视图停止时的时候 - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{ CGFloat wid ...

  9. Largest product in a series

    这个我开始理解错了,算错了. 我以为是求连续5个数的最大值,结果,是连接5个数相乘的最大值. 英语不好,容易吃亏啊. Find the greatest product of five consecu ...

  10. atof

    So given a string like "2.23" your function should return double 2.23. This might seem eas ...