1, 模板观念与函数模板
简单模板:
template< typename T > T Function( T a, T b) {… }
类模板:
template struct Object{……….};
函数模板
template< class T> inline T Function( T a, T b){……}
不可以使用不同型别的参数来调用函数模板
可以使用class代替typename. 但不能使用struct代替typename
使用具体类型代替模板参数T叫实例化, 从而产生一个模板实例.
模板编译过程:
实际编译两次
1,没有实例化前,检查模板代码本身检查是否有语法错误
2,实例化期间,检查模板代码的调用是否合法
模板编译
1,类型必须严格符合,不可自动型别转换.
2,如果真的要转换,那么需要使用static_cast< …>进行强制转换.
函数模板重载
1, 模板函数可以像普通函数一样被重载
2, 非模板函数可以和同名模板函数共存
3, 编译器通过函数模板参数推导来决定使用哪个重载
其他因素相同的情况下,重载裁决过程调用非模板函数.
(否则编译器还需要自己在实例化一套代码)
Max<>(7,32) 调用Max允许空模板参数
Max(2,3) 显式指定模板实参类型
2, C++类模板
template < typename T, size_t n = 1024> class Stack{……..};
a,关键字 typename 和class 都可使用
b,在模板内, T可以像int,char一样 定义成员变量和成员函数
c,除了Copy constructor之外, 如果在类模板内需要使用到这个类本身,如定义operator=,那麽应该使用其完整定义(Stack)
Stack& operator=( Stack < T,n> const & );
类模板的使用:
1,Stack s;
2,Stack< int,100> s;
1,Stack< Stack > s; 定义一个Stack的Stack , 此处必须有一个空格, 否则编译器会以为是>>操作符
3, 类模板特化
template<>
class Stack{……};
可能可以做些特别的优化或者提供不同的实现
避免在实例化某些类时,引起一些可能产生的诡异行为
4, 类模板偏特化
主模板:
template< typename T1, typename T2> class MyClass{…};
偏特化:
2
template< typename T> class MyClass< T,T>{…};
3
template< typename T> class MyClass< T,int>{…};
4
template< typename T1, typename T2> class MyClass< T1*,T2*>{…};
如果有不止一个偏特化同程度的能匹配某个调用,那么该调用具有二义性,ERROR.
如 :
MyClass< int, int> obj; 满足 MyClass< T,T> 和 MyClass< T,int>
MyClass< int*, int*> obj; 满足 MyClass< T1*,T2* > 和 MyClass< T,T>
5, 默认模板实参
template< typename T, typename Tcons = std::vetor< T> > class Stack{…};
6, 操作符重载
除了 operator= ,其他操作符都可以被重载.
7, 特性(Traits) - 重点
Traits可以实现为模板类, 而关联则是针对每个具体型别T的特化.
template< typename T > class Simg{ };
template< > class Simg< char>{
public: typedef int ReturnType ;
};
template< > class Simg< short>{
public: typedef int ReturnType ;
};
template< > class Simg< int>{
public: typedef long ReturnType ;
};
Traits实现: (函数定义)
template< typename T>
typename Simg< T >::ReturnType Sigma ( const T const* Start, const T const* end)
{
Simg< T >::ReturnType type;
type r = ReturnType();
return r ; //这里返回的就是特性的新类型
}
8, 迭代器
用于分离算法和容器
智能指针