在C++什么是泛型编程程中如何只特化类的一个成员函数

在C++范型编程中如何只特化类的一个成员函数
在C++范型编程中如何只特化类的一个成员函数
  我们知道在C++模板编程中如果我们特化或是偏特化某个模板类, 我们需要重写整个模板类中的所有函数, 但是这些代码通常是非常相似的, 甚至在某些情况下可能只有一两个函数会不一样,其他函数都是一样的。在这种情况下,同时存在多份相同的代码,对我们维护这些代码是非常不利的, 我们最好只需要特化其中不一样的那个函数。比如下面这个模板类:&&& template&&& struct Base&&& {&&& //other function&&& //…&&& void Func(){ cout 《 "primary function" 《 }&&& };&&& void test1()&&& {&&& B&&& a.Func();&&& B&&& b.Func();&&& }&&& int main()&&& {&&& test1();&&& }&&& 只有当B等于16时, Func这个函数需要特化, 但是其他函数无论什么情况下都是一样的。下面是我们的一些可能解决方案:&&& 方法1:&&& template&&& struct Base&&& {&&& //other function&&& //…&&& void Func(){ cout 《 "specialization function" 《 }&&& };&&& 点评:通过偏特化实现,需要重写所有的类成员方法。&&& 方法2:&&& template&&& struct Base&&& {&&& //other function&&& //…&&& void Func()&&& {&&& if(B == 16)&&& {&&& cout 《 "primary function" 《&&& }&&& else&&& {&&& cout 《 "specialization function" 《&&& }&&& }&&& };&&& 点评: 通过运行时判断, 容易理解,但是相对低效。
  方法3:&&& template&&& struct Base&&& {&&& //other function&&& //…&&& void Func()&&& {&&& #if B!=16&&& cout 《 "primary function" 《&&& #else&&& cout 《 "specialization function" 《&&& #endif&&& }&&& };&&& 点评: 试图通过预编译来实现,但是这个方法是错误的。C++模板编译包括预编译,语法检查,模板实例化等阶段,在预编译阶段模板参数都还没有实例化呢。&&& 方法4:&&& template&&& struct Base&&& {&&& //other function&&& //…&&& template&&& struct FuncObj&&& {&&& void operator()()&&& {&&& cout《"primary function"&&&& }&&& };&&& template&&&&& struct FuncObj&16&&&& {&&& void operator()()&&& {&&& cout《"specialization function"&&&& }&&& };&&& FuncObj F&&& };&&& 点评: 通过成员类以防函数的形式特化, 增加了类成员变量。&&& 方法5:&&& template&&& struct Base&&& {&&& //other function&&& //…&&& template&&& void FuncImpl()&&& {&&& cout《"primary function"&&&& }&&& template&&&&& void FuncImpl&16&()&&& {&&& cout《"specialization function"&&&& }&&& void Func()&&& {&&& FuncImpl();&&& }&&& };&&& 点评:通过类成员模板函数特化来实现。&&& 方法6:&&& template&&& struct Base&&& {&&& //other function&&& //…&&& template&&& class Int2Type&&& {&&& enum { value = N };&&& };&&& template&&& void FuncImpl(const Int2Type)&&& {&&& cout《"primary function"&&&& }&&& void FuncImpl(const Int2Type&16&)&&& {&&& cout《"specialization function"&&&& }&&& void Func()&&& {&&& FuncImpl(Int2Type());&&& }&&& };&&& 点评: 通过将int根据值的不同转成不同的类型,然后通过函数重载实现。&&& 方法7:&&& namespace&&& {&&& template struct conditional { typedef T };&&& template struct conditional {typedef U };&&& }&&& template&&& struct Base&&& {&&& //other function&&& //…&&& void Func ()&&& {&&& typedef typename ::conditional::&&& Func_impl(type());&&& }&&& private:&&& struct primary_t { };&&& struct spec_t { };&&& void Func_impl (primary_t) { std::cout 《 "primary function" 《 std:: }&&& void Func_impl (spec_t ) { std::cout 《 "specialization function" 《 std:: }&&& };&&& 点评: 和方法6类似,通过函数重载实现&&& 方法8:&&& namespace&&& {&&& template struct enable_if { typedef T };&&& template struct enable_if {};&&& }&&& template&&& struct Base&&& {&&& //other function&&& //…&&& template&&& typename ::enable_if&16!=N&::type&&& FuncImpl () { std::cout 《 "primary function" 《 std:: }&&& template&&& typename ::enable_if&16==N&::type&&& FuncImpl () { std::cout 《 "specialization function" 《 std:: }&&& void Func() {&&& FuncImpl();&&& }&&& };&&& 点评:通过enable_if, 利用SFINAE实现。&&& 我们可以看到根据编译时模板参数int值的不同,我们重写模板类的某个成员函数的方法是多种多样的。针对上面这种情况,个人其实最推荐方法2,我们没必要把简单的问题复杂化。&&& 下面我们考虑另外一个需求, 当模板类的某个参数是某种类型时, 我们要求特化其中的一个成员函数:&&& template&&& struct Base&&& {&&& //other function&&& //…&&& void Func(){ cout 《 "primary function" 《 }&&& };&&& void test2()&&& {&&& B&&& a.Func();&&& B&&& b.Func();&&& }&&& int main()&&& {&&& test2();&&& }&&& 要求上面的模板类如果T2 是string类型, 我们要求对Func特殊重写,其他的成员函数无论什么情况实现都是一样的。
  有了上面的那个例子的实现经验, 对这个问题我们解决就方便多了。&&& 方法1:&&& template&&& struct Base&&& {&&& //other function&&& //…&&& void Func()&&& {&&& if(typeid(std::string) == typeid(T2))&&& {&&& cout《"specialization function"&&&& }&&& else&&& {&&& cout 《 "primary function" 《&&& }&&& }&&& };&&& 点评:通过运行时类型识别(RTTI)实现,需要打开相关编译选项,并且低效。&&& 方法2:&&& template&&& struct Base&&& {&&& //other function&&& //…&&& template&&& void FuncImpl()&&& {&&& cout 《 "primary function" 《&&& }&&& template&&&&& void FuncImpl()&&& {&&& cout 《 "specialization function" 《&&& }&&& void Func()&&& {&&& FuncImpl();&&& }&&& };&&& 点评:通过成员函数特化实现&&& 方法3:&&& template&&& struct Base&&& {&&& //other function&&& //…&&& template&&& class Type2Type&&& {&&& typedef T&&& };&&& template&&& void FunImpl(const Type2Type)&&& {&&& cout 《 "primary function" 《&&& }&&& template&&& void FunImpl(const Type2Type)&&& {&&& cout 《 "specialization function" 《&&& }&&& void Func()&&& {&&& FunImpl(Type2Type());&&& }&&& };&&& 点评: 通过函数重载实现&&& 方法4:&&& template&&& struct IsString&&& {&&& enum { value = false };&&& };&&& template&&&&& struct IsString&&& {&&& enum { value = true };&&& };&&& template&&& struct Base&&& {&&& //other function&&& //…&&& void Func()&&& {&&& if(IsString::value)&&& {&&& cout 《 "specialization function" 《&&& }&&& else&&& {&&& cout 《 "primary function" 《&&& }&&& }&&& };&&& 点评: 通过编译时类型判断实现。&&& 方法5:&&& template&&& struct must_be_same_type&&& {&&& enum { ret = 0 };&&& };&&& template&&&&& struct must_be_same_type&&& {&&& enum { ret = 1 };&&& };&&& template & typename T1,typename T2 &&&& class Base{&&& public:&&& //other function&&& //…&&& void Func(){&&& if(must_be_same_type::ret)&&& {&&& cout 《 "specialization function" 《&&& }&&& else&&& {&&& cout 《 "primary function" 《&&& }&&& }&&& };&&& 点评: 和方法4类似, 是不过实现方式不一样。&&& 最后,探讨下我自己遇到的问题, 我们在写一个事件委托(delegate)类,大概如下:&&& template&&& class CEvent&&& {&&& public:&&& //other function&&& //…&&& return_type operator()(first_type p1, second_type p2)&&& {&&& return_type ret = return_type();&&& //…&&& //ret = invoker(p1, p2);&&&&&& }&&& };&&& void test3()&&& {&&& CEvent e1;&&& e1(1, 2);&&& CEvent e2;&&& e2(1, 2);&&& }&&& int main()&&& {&&& test3();&&& }&&& 我们可以看到,当return_type是void时, 因为没有返回值,上面的代码会编译失败,因此我们只能偏特化这种情况:&&& template&&& class CEvent&&& {&&& public:&&& //other function&&& //…&&& void operator()(first_type p1, second_type p2)&&& {&&& //…&&& //invoker(p1, p2);&&&&&& }&&& };&&& 但是,我们会发现只有这个operator()函数是需要根据return_type特殊对待的,其他函数永远都是一样的。&&& 我们现在的问题就是如何只特化这个函数。&&& 首先我们会想到如下的实现方法:&&& template&&& struct IsVoid&&& {&&& enum { value = false };&&& };&&& template&&&&& struct IsVoid&&& {&&& enum { value = true };&&& };&&& template&&& class CEvent&&& {&&& public:&&& other function&&& …&&& return_type operator()(first_type p1, second_type p2)&&& {&&& if(IsVoid::value)&&& {&&& cout 《 "return type is void" 《&&& //…&&& //invoker(p1, p2);&&& }&&& else&&& {&&& cout 《 "return type is not void" 《&&& return_type ret = return_type();&&& //…&&& //ret = invoker(p1, p2);&&&&&& }&&& }&&& };&&& 但是我们很快会发现这种情况下if语句被编译进去了, 所以return_type是void的情况下还是会编译失败。&&& 我们要解决的问题就是如何把这个if语句变成函数重载,于是我们想到如下实现:&&& template&&& struct IsVoid&&& {&&& enum { value = false };&&& };&&& template&&&&& struct IsVoid&&& {&&& enum { value = true };&&& };&&& template&&& class Int2Type&&& {&&& enum {value = v };&&& };&&& template&&& class CEvent&&& {&&& public:&&& //other function&&& //…&&& return_type InvokerImpl(first_type p1, second_type p2, Int2Type)&&& {&&& cout 《 "return type is void" 《&&& //…&&& //invoker(p1, p2);&&& }&&& return_type InvokerImpl(first_type p1, second_type p2, Int2Type)&&& {&&& cout 《 "return type is not void" 《&&& return_type ret = return_type();&&& //…&&& //ret = invoker(p1, p2);&&&&&& }&&& return_type operator()(first_type p1, second_type p2)&&& {&&& return InvokerImpl(p1, p2, Int2Type::value&());&&& }&&& };&&& 上面的实现首先通过编译时类型识别,然后再把识别后相应的bool值转成不同类型, 最后再利用不同类型函数重载实现。&&& 最后总结下,我们可以看到,从编译时到运行时,从面向对象到普通范型编程再到模板元编程,C++复杂得让人无语, 也强大得让人无语, 而且C++语言本身是在不断发展的(C++11), 同一问题在C++中往往有多种解决方案,这些解决方案有的简单,有的复杂,有的高效, 也有的低效, 而我们的目标就是利用C++这把利器寻找简单而高效的解决方案。
H3C认证Java认证Oracle认证
基础英语软考英语项目管理英语职场英语
.NETPowerBuilderWeb开发游戏开发Perl
二级模拟试题一级模拟试题一级考试经验四级考试资料
软件测试软件外包系统分析与建模敏捷开发
法律法规历年试题软考英语网络管理员系统架构设计师信息系统监理师
高级通信工程师考试大纲设备环境综合能力
路由技术网络存储无线网络网络设备
CPMP考试prince2认证项目范围管理项目配置管理项目管理案例项目经理项目干系人管理
职称考试题目
招生信息考研政治
网络安全安全设置工具使用手机安全
生物识别传感器物联网传输层物联网前沿技术物联网案例分析
Java核心技术J2ME教程
Linux系统管理Linux编程Linux安全AIX教程
Windows系统管理Windows教程Windows网络管理Windows故障
数据库开发Sybase数据库Informix数据库
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&博客访问: 29305
博文数量: 58
注册时间:
鏆傛棤浠嬬粛
ITPUB论坛APP
ITPUB论坛APP
APP发帖 享双倍积分
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: IT综合技术
在上一期专栏中我已经谈到过,执行的操作不仅包括简单存储和检索操作的参数化类型仅限于可安全绑定到它的可接受类型 [请参阅 (英文)]。使用泛型,可以通过 where 子句显式加上这些限制。在 C++/CLI 模板工具中,通过将函数模板或类模板(单个成员函数或整个类)特殊化,通常可以避免这些限制。例如,将 min 函数添加到上一期专栏的 tStack 类中。通常,我会使用常规 min 算法,但那种算法仅在我作为程序员的时候有用,而对我撰写有关模板特殊化的文章没有帮助。为了方便起见, 中重现了 tStack 类的模板定义。[@more@] 显示了 min 的一种可能的实现方法。我将定义一个局部变量 min_val 来存放最小元素,并将它初始化为容器的第一个元素。然后定义两个迭代程序,将每个元素与 min_val 进行比较,如果其值比 min_val 小则为 min_val 重新赋值。现在,您能看出隐含的限制吗?如果能,则您会得到: if ( *it < min_val )
通常,对于 min 函数,只有能够使用内置小于 (<) 运算符的类型或本身具有 operator<() 实例的类型才能绑定到 elemType 的类型。如果某个类型没有定义 operator<(),并尝试对此类型的项的 tStack 调用 min,则在 min 中使用无效的比较运算符时将出现编译时错误。例如,System::String 类没有小于 (<) 运算符(它使用 IComparable 的 CompareTo 方法)。因此,如果我尝试对使用 String 实例化的 tStack 调用 min,则它在编译时就会出错,因为该比较操作失败了。有一种解决方案我不会使用:定义全局运算符 operator<(),该运算符使用 CompareTo 来比较两个 String 类型的值。然后,tStack::min() 会自动调用这些全局运算符: bool operatorCompareTo( s2 ) < 0 ) ? true :
请记住,目标是防止当用户指定的类型参数为 String 时实例化 tStack::min 成员函数定义,而希望使用 CompareTo 方法来定义自己的 tStack::min 实例。您可以使用显式模板特殊化定义为类模板实例化的成员提供特殊化的定义,来实现此目的。此定义指明了模板名称、指定模板的参数、函数参数列表和函数主体。关键字模板的后面是小于 () 标记,然后是类成员特殊化的定义(请参阅)。即使类的类型 tStack 是从常规类模板定义(即由编译器内部生成的专用于 String 的实例,其中每个 elemType 占位符都被替换为 String 类型)实例化的,类型 tStack 的每个对象都会调用特殊化的成员函数 min。tStack::min 成员函数定义既不会被扩展,也不会在 tStack 中使用。在有些情况下,可能整个类模板定义都不适合某种类型。在这种情况下,程序员可以提供一种定义来特殊化整个类模板。程序员可以提供 tStack 的定义: template
ref class tS
// 类模板特殊化
template ref class tStack {
String^ pop();
void push( Stack^ et );
只有在声明了常规类模板后,才能定义显式类模板特殊化。如果您提供完整的类模板特殊化,则必须定义与此特殊化关联的每个成员函数或静态数据成员。类模板的常规成员定义决不能用于创建显式特殊化的成员定义,也不会被交叉检查。这是因为类模板特殊化的类成员集可能与常规模板的类成员集完全不同。定义完全特殊化的类模板(如 tStack)的成员时,请勿在其定义前添加特殊的 template 标记,而应该通过显式列出实际的类型来指明特殊化定义,如下所示: // 定义类模板特殊化的
// 成员函数 min()
String^ tStack::min() { ... }
局部模板特殊化如果类模板有多个模板参数,您可以针对一个或一组特定的参数化值或类型来特殊化类模板。也就是说,您可能希望提供一个模板,使其除了某些模板参数已被实际类型或实际值替换以外,其他均与常规模板匹配。使用局部模板特殊化就可以实现此目的。例如,假设存在下面的 Buffer 类模板: template
ref class Buffer { ... };
下面说明如何对 Buffer 使用局部特殊化,使其能够很好地处理大小为 1KB 的缓冲区: // 类模板 Buffer 的局部特殊化
ref class Buffer {
// 对 1KB 大小使用特殊算法...
Buffer 的局部特殊化只有一个类型参数 elemType,因为大小的值固定为 1024。局部模板特殊化的参数列表只列出了模板参数仍然未知的参数。但是,当您定义该模板的实例时,必须同时指定这两个参数(这与对一个参数使用默认值的情形不同)。在下面的示例中,局部类模板特殊化是用 elemType 为 String 的类型参数实例化的: Buffer
但是,如果您改为下面的代码行,则编译器会生成错误,并将声明标记为缺少第二个参数: Buffer
为什么会这样呢?如果开发人员以后引入一组特殊化的 Buffer(如下所示),会出现什么情况? template
ref class Buffer {};
ref class Buffer {};
如果前面示例的声明中不要求使用第二个参数,编译器就无法区分这几种特殊化!局部特殊化与其对应的完整常规模板同名,在本例中为 Buffer。这就带来了一个有趣的问题。请注意,Buffer 的实例化既可以通过类模板定义进行,也可以通过局部特殊化进行。那么,为什么会选择局部特殊化来实例化该模板呢?一般的规则是:如果声明了局部类模板特殊化,编译器就会选择最特殊化的模板定义进行实例化。只有在无法使用局部特殊化时,才会使用常规模板定义。例如,当必须实例化 Buffer 时,由于此实例化与任何一个局部模板特殊化都不匹配,因此会选择常规模板定义。局部特殊化的定义完全不同于常规模板的定义。局部特殊化可以拥有一组与常规类模板完全不同的成员。局部类模板特殊化的成员函数、静态数据成员和嵌套类型必须有自己的定义,这与类模板特殊化相同。类模板成员的常规定义决不能用于实例化局部类模板特殊化的成员。类模板的局部模板特殊化构成了现代 C++ 用法中一些非常复杂的设计惯用语的基础。如果您对此感兴趣,可以阅读 Andrei Alexandrescu 撰写的《Modern C++ Design: Generic Programming and Design Patterns Applied》(Addison-Wesley,2001 年版),了解此用法的详细信息。函数模板特殊化非成员函数模板也可以进行特殊化。在有些情况下,您可以充分利用有关类型的一些专门知识,来编写比从模板实例化的函数更高效的函数。在其他一些情况下,常规模板的定义对某种类型而言根本就是错误的。例如,假设您拥有函数模板 max 的定义: template
T max( T t1, T t2 ) {
return ( t1 > t2 ? t1 :t2 );
如果用 System::String 类型的模板参数实例化该函数模板,所生成的实例就无法编译,因为正如您在前面所看到的,String 类不支持小于 () 运算符。 中的代码说明了如何特殊化函数模板。(同样必须先声明常规函数模板才能进行特殊化。)如果可以从函数参数推断出模板参数,则可以从显式特殊化声明中对实际类型参数省略函数模板名称的限定 max。例如,编译器可以在下面的 max 模板特殊化中推断出 T 绑定到 String,因此在这种情况下,为方便起见,该语言允许使用下面的简写表示法: // 没问题:从参数类型推断出 T 绑定到 String
template String^ max( String^, String^ );
引入此显式特殊化后,下面的调用就会解析为这个特殊化的实例:
void foo( String^ s1, String^ s2 ) {
String^ maxString = max( s1, s2 );
如果两个参数的类型均为 String,常规函数模板不会扩展。这正是我们所需要的行为。只要提供了显式函数模板特殊化,就必须始终指定 template 和函数参数列表。例如,max 的下面两个声明不合法,并且在编译时会被标记为: // 错误:无效的特殊化声明
// 缺少 template
String^ max( String^, String^ );
// 缺少函数参数列表
template String^ max;
有一种情况,省略函数模板特殊化的 template 部分不是错误。即,在您声明的普通函数带有与模板实例化相匹配的返回类型和参数列表的情况下: // 常规模板定义
T max( T t1, T t2 ) { /* ... */ }
// 没问题:普通函数声明!
String^ max( String^, String^ );
毫无疑问,您经常会感到很无奈,并认为 C++ 真是太难理解了。您可能想知道,究竟为什么所有人都希望声明与模板实例化相匹配的普通函数,而不希望声明显式特殊化。那么,请看下面的示例,事情并不是完全按照您喜欢的方式进行的: void foo( String^ s1, String^ s2 ) {
// 能否解析特殊化的实例?
String^ maxString = max( "muffy", s2 );
在 C++/CLI 下,对于重载解决方案,字符串文字的类型既是 const char[n] [其中 n 是文字的长度加一(用于终止空字符)],又是 System::String。这意味着,给定一组函数 void f( System::String^ );
void f( const char* );
void f( std::string );
如下所示的调用 // 在 C++/CLI 下解析为 (1)
f( "bud, not buddy" );
与 (1) 完全匹配,而在 ISO-C++ 下,解析结果会是 (2)。因此,问题就是,对于函数模板的类型推断而言,字符串文字是否还是被当作 System::String 进行处理?简言之,答案是“不”。(详细的答案将是我下一期专栏的主题,该专栏将详细介绍函数模板。)因此,不选择 max 的特殊化 String 实例,下面对 max 的调用 String^ maxString = max( "muffy", s2 ); // 错误
在编译时会失败,因为 max 的定义要求两个参数的类型均为 T: template
T max( T t1, T t2 );
那您能做些什么呢?像在下面的重新声明中一样,将模板改为带有两个参数的实例 template
??? max( T1 t1, T2 t2 );
使我们能够编译带有 muffy 和 s2 的 max 的调用,但会因大于 (>) 运算符而断开;并且指定要返回的参数类型。 我想做的就是始终将字符串文字强制转换为 String 类型,这也是挽救普通函数的方法。如果在推断模板参数时使用了某个参数,那么只有一组有限的类型转换可用于将函数模板实例化的参数转换为相应的函数参数类型。还有一种情况是显式特殊化函数模板。正如您所看到的,从字符串文字到 System::String 的转换不属于上述情况。在存在有害字符串文字的情况下,显式特殊化无助于避免对类型转换的限制。如果您希望不仅允许使用一组有限的类型转换,则必须定义普通函数而不是函数模板特殊化。这就是 C++ 允许重载非模板函数和模板函数的原因。我基本上已经讲完了,不过还有最后一点需要说明。创建一组您在 中看到的 max 函数意味着什么?您知道调用 max( 10, 20 );
始终会解析为常规模板定义,并将 T 推断为 int。同样,您现在还知道调用 max( "muffy", s2 );
max( s2, "muffy" );
始终会解析为普通函数实例(其中文字字符串转换为 System::String),但是有一个问题,调用 max( s2, s2 );
会解析为三个 max 函数中的哪一个?要回答此问题,我们要查看解析重载函数的过程。 重载函数的解析过程解析重载函数的第一步是建立候选函数集。候选函数集包含与被调用的函数同名并且在调用时能够看到其声明的函数。第一个可见函数是非模板实例。我将该函数添加到候选列表中。那么函数模板呢?在能够看到函数模板时,如果使用函数调用参数可以实例化函数,则该模板的实例化被视为候选函数。在我的示例中,函数参数为 s2,其类型为 String。模板参数推断将 String 绑定到 T,因此模板实例化 max(String^,String^) 将添加到候选函数集中。只有在模板参数推断成功时,函数模板实例化才会进入候选函数集。但是,如果模板参数推断失败,不会出现错误;即,函数实例化没有添加到候选函数集中。如果模板参数推断成功,但是模板是为推断出的模板参数显式特殊化的(正如我的示例一样),会怎么样呢?结果是,显式模板特殊化(而不是通过常规模板定义实例化的函数)将进入候选函数。因此,此调用有两个候选函数:特殊化的模板实例化和非模板实例。 // 候选函数
// 特殊化的模板...
template String^ max( String^ s1, String^ s2 );
// 非模板实例
String^ max( String^, String^ );
解析重载函数的下一步是从候选函数集中选择可行函数集。对于要限定为可行函数的候选函数,必须存在类型转换,将每个实际参数类型转换为相应的形式参数类型。在该示例中,两个候选函数都是可行的。解析重载函数的最后一步是,对参数所应用的类型转换进行分级,以选择最好的可行函数。例如,两个函数看起来都很好。既然两个函数都可行,那么这是否应该被视为不明确的调用?实际上,调用是明确的:将调用非模板 max,因为它优先于模板实例化。原因是,在某种程度上,显式实现的函数比通过常规模板创建的实例更为实用。令人吃惊的是,在解决有害字符串文字的情况中,我已经彻底消除了调用以前的 String 特殊化的可能性,因此我可以消除这个问题。我只需要常规模板声明以及重载的非模板实例: // 支持 String 的最终重载集
T max( T t1, T t2 ) { /* ... */ }
String^ max( String^, String^ );
这不一定会很复杂,但有一点是肯定的 - 在语言集成和灵活性方面,它远远地超过了公共语言运行时 (CLR) 泛型功能可以支持的范围。 模板特殊化是 C++ 模板设计的基础。它提供了最好的性能,克服了对单个或系列类类型的限制,具有灵活的设计模式,并且在实际代码中已证实其巨大价值。在下一期专栏中,我将深入分析 C++/CLI 对模板函数和常规函数的支持。请将您的疑问和意见通过
发送给 Stanley。Stanley B. Lippman 是 Microsoft 公司 Visual C++ 团队的体系结构设计师。他从 1984 年开始在 Bell 实验室与 C++ 的设计者 Bjarne Stroustrup 一起研究 C++。此后,他在 Disney 和 DreamWorks 制作过动画,还担任过 JPL 的高级顾问和 Fantasia 2000 的软件技术主管。
阅读(832) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。}

我要回帖

更多关于 泛型编程与stl 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信