background image

  4. 模板的类型推导对于函数,编译器是知道传入参数的类型的,比如上
面的 max,max<   

? >  

( x  

, y 

 

),由于第一个参数 x   

是 int 类型的,那么 

 

? 这里需要填写什么呢?

 

  我们可以很明显的推断出应该是 "int",否则,后面的强类型系统将无法

 

编译这个函数。编译器同样知道 x 

的类型,因此它也能推导出 类型参数 ,这

时候我们调用时就可省略模板参数了。

 

  这个推导是按顺序来的,因此如果上面的 y 

 

是其他类型,? 仍然会被推

 

导为 int,如果 y 无法隐性转换为 int,强类型编译时就会报错。

  5. 类型推导的隐式类型转换在决定模板参数类型前,编译器执行下列隐
式类型转换:

  左值变换修饰字转换派生类到基类的转换

  见《C++ Primer》([注 2],P500)对此主题的完备讨论。

  简而言之,编译器削弱了某些类型属性,例如我们例子中的引用类型的
左值属性。举例来说,编译器用值类型实例化函数模板,而不是用相应的引用
类型。

  同样地,它用指针类型实例化函数模板,而不是相应的数组类型。

  它去除 const 修饰,绝不会用 const 类型实例化函数模板,总是用相应

 

的非 const

 

类型,不过对于指针来说,指针和 const 指针是不同的类型。

  底线是:自动模板参数推导包含类型转换,并且在编译器自动决定模板
参数时某些类型属性将丢失。这些类型属性可以在使用显式函数模板参数申明
时得以保留。

  6. 模板的偏特化如果我们打算给模板函数(类)的某个特定类型写一个

 

函数,就需要用到模板的偏特化,比如我们打算用 long 

 

类型调用 max 的时

候,返回小的值(原谅我举了不恰当的例子):template<> // 这代表了下
面是一个模板函数 long max<long>  

( long a  

, long b   

) // 

 

对于 vc 来说,

 

这里的 <long> 是可以省略的{ return a > b   

? b   

: a;}实际上,所谓偏

特化,就是代替编译器完成了对指定类型的特化工作,现代的模板库中,大
量的使用了这个技巧。

  7. 

 

仿函数仿函数这个词经常会出现在模板库里(比如 STL),那么什么

是仿函数呢?

  顾名思义:仿函数就是能像函数一样工作的东西,请原谅我用东西这样
一个代词,下面我会慢慢解释。