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),那么什么
是仿函数呢?
顾名思义:仿函数就是能像函数一样工作的东西,请原谅我用东西这样
一个代词,下面我会慢慢解释。