注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

模板的特化和模板元编程<续>  

2013-04-26 21:38:52|  分类: C++(VC)编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

模板的特化和模板元编程<>

在前面讲类的模板时,对全特化和显示实例化(显示特化),[这里叫显示特化不对,二者不是一回事,弄错了,显示特化,全特化,明确特化,这是一回事。2016-04-28]讲到过他们是一致的,看引用的英文资料,但在今天中看侯捷的C++TEMPLATE,发现,还是有一些区别,所以上网查了下资料,结果发现,确实是区别还是挺明显的.

显示实例化(explicit  instantiation),无论是函数模板还是类模板都只能实现一次,可是大家发现了,全特化(full specialization)可以有好几种,另外大家可以发现函数模板和类模板的显示特化与全特化还是有一些细微不同的:

类的显示特化:

template <class T>

class D

{

public:

         T f();

 

};

//类的显示实例化--只能实例化一次

template class D<int>;

函数模板的显示特化:

template<class Type> Type sum( Type op1, int op2 ); //{return op1;}//可以声明与实现一起

//与下一行不能同时存在,不知道实例化和具体化的二者的区别

template int* sum< int* >( int*, int ); //模板函数显示实例化---只需要声明

注意到没有,template后面没<>这对尖括号.这到底是不是二者的区别,现在还没有找到权威的说明,也或者二者是不同的表现形式而已.

那么,这个显示特化有什么作用呢?一直在考虑,这么个东西没有实现,又有什么作用呢?经过在网上搜索,终于找到了说明:

http://msdn.microsoft.com/zh-tw/library/by56e477(v=vs.100).aspx

MSDN上说,可以给库使用(LIB),” Explicit instantiation lets you create an instantiation of a templated class or function without actually using it in your code. Because this is useful when you are creating library (.lib) files that use templates for distribution, uninstantiated template definitions are not put into object (.obj) files.”

当看到没有初始化的模板不能编译进OBJ文件,再想到原来的分享编译,终于明白了这个用处,非常巧妙.

另外还一个用处,” You can use the extern keyword to prevent the automatic instantiation of members. For example:”

 extern template class MyStack<int, 6>;

Similarly, you can mark specific members as being external and not instantiated as follows:

extern template MyStack<int, 6>::MyStack( void );

Note

The extern keyword in the specialization only applies to member functions defined outside of the body of the class. Functions defined inside the class declaration are considered inline functions and are always instantiated.

下面的资料转自:

http://www.phpfans.net/article/htmls/201004/Mjg0NTEy.html

C++0x外部模板(Extern Template

作者: tyc611  时间: 2010-04-21

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

转载完毕,非常感谢无私奉献的网友.

学会站在巨人的肩膀上,是我们既稳又快前进的有力保证.

  评论这张
 
阅读(786)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017