C++:模板

模板(Template)

1. 类模板(class template)

设计类时,将一些类型抽出来,允许使用者任意指定

  • 基本示例
template<typename T>
class complex
{
public:
    complex (T r=0,T i=0)
        :re(r),im(i){}
    complex& operator +=(const complex&);
    T real()const{return re;}
    T imag()const{return im;}
private:
    T re,im;
    friend complex& _doapl(complex*,const complex&);
};


int main()
{
    complex<double> d1(2.5,1.5);
    complex<int> c2(2,6);
}

2. 函数模板(function template)

设计函数时,抽出变量类型,允许使用者任意指定

  • 基本示例
template<typename T>      //T只为一个符号,自己取名,避免与关键字冲突
inline const T& min(const T& a,const T& b)
{
	return b<a?b:a;
}

class stone
{
public:
	stone(int w,int h,int we):_w(w),_h(h),_weight(we){}
	bool operator< (const stone& rhs)const{return _weight<rhs._weight;}
private:
	int _w,_h,_weight;
};


stone r1(2,3),r2(3,3),r3;
r3 = min(r1,r2);         //在min()中编译器推导T为stone,于是调用stone::operator<
  • 编译器会对函数模板进行实参推导(argument deduction

3. 成员模板(member template)

  • 具体示例:下述代码中template <class U1,class U2>为成员模板
template <class T1,class T2>
struct pair{
	typedef T1 first_type;
	typedef T2 second_type;
	
	T1 first;
	T2 second;
	
	pair():first(T1()),second(T2()){}
	pair(const T1& a,const T2& b):first(a),second(b){}
	
	template <class U1,class U2>
	pair(const pair<U1,U2>&p):first(p.first),second(p.second){}

};
  • 应用上述代码如下
class Base1{  };
class Derived1:public Base1{  };

class Base2{  };
class Derived2:public Base2{  };

pair<Derived1,Derived2> p;
pair<Base1,Base2> p2(p);

//上面两行代码合为以下:
pair<Base1,Base2> p2(pair<Derived1,Derived2>()); //这里Base1,Base2为T1,T2,Derived1,Derived2为U1,U2

4. 模板特化(specialization)

// 泛化
template <class Key> 位置1
struct hash{};

// 特化
template<>  //仍及保留template,但是<>里面不加入东西 
struct hash<char>{    //位置2
	size_t operator () (char x) const { return x; }
};

template<>      //位置3
struct hash<int>{ 
	size_t operator () (int x) const { return x; }
};

template<>        //位置4
struct hash<long>{
	size_t operator () (long x) const { return x; }
};

//测试
cout << hash<long>()(1000);   //hash<long>()获得一个临时变量,且调用的是位置4处,后面的(1000)则调用覆写的()方法 

5. 模板偏特化(partial specialization)

  1. 个数的偏特化:参数必须从左到右顺序特化,而不能跳跃;
//泛化
template<typename T,typename Alloc=...>  //两个模板参数
class vector
{
...
};

//个数上的偏特化
template<typename Alloc=...>
class vector<bool,Alloc>
{
...
};
  1. 范围的偏特化:设计接收任意类型的T,将范围缩小为指针指向任意类型;
template <typename T>
class C    //如果使用者使用的不是指针就用这套代码
{
...
};

//范围上的偏特化
template <typename T>   //此处的T也可换成另外一个符号,如U,此处的T与上面的T无关
class C<T*>   //如果使用者使用的指针就用这套代码
{
...
};

C<string> obj1;

C<string*> obj2;

6. 模板模板参数 (template template parameter)

  • 具体示例
template< typename T,
		  template<typename T>
		  	class Container
		>
class XCls
{
private:
	Container<T> c;
public...
};

//测试
template<typename T>
using Lst = list<T,allocator<T>>;

XCls<string,list> mylst1;  //语法错误,此处代码将Container<T> c转为list<string> c,未指定第二个模板模板参数

XCls<string,Lst> mylst2;
  • 非模板模板参数
template <class T,
		  class Sequence = deque<t> //这不是模板模板参数
		 >
 class stack{
 	friend bool operator== <>(const stack&,const stack&);
 	friend bool operator< <>(const stack&,const stack&);
 protected:
 	Sequence c;  //底层容器
 };
 
 
 //测试
 stack<int> s1; //由于第二个模板参数有默认指定,可以只指定第一个模板参数
 stack<int,list<int>> s2;  //此处的list<int>已经写死,不是模板了
  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值