C++模板和STL

在这里插入图片描述

模板

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

函数模板的定义

在这里插入图片描述
在这里插入图片描述

#include <iostream>
using namespace std;

//函数模板,"T"类型形参
template <typename T>   //推荐使用typename 
//template <class T>
T max(T x, T y){
   
  return x<y?y:x;
}
int main(void){
   
  int  i1=100,i2=200;
  // "<>"指明函数模板需要的类型实参
  // "()"指明函数的调用实参
  cout<<::max<int>(i1,i2)<<endl;

  double d1=1.23,d2=4.56;
  cout<<::max<double>(d1,d2)<<endl;

  string s1="world",s2 = "hello";
  cout<<::max<string>(s1,s2)<<endl;

  char str1[] = "world";
  char str2[] = "hello";
  cout<<::max<string>(str1,str2)<<endl;
  return 0;

}

函数模板的使用

在这里插入图片描述

模板实例化

在这里插入图片描述

类型参数

在这里插入图片描述

参考代码

#include <iostream>
using namespace std;
template <typename T>
T add(T x,T y){
   
  return x+y;
}
class Complex{
    //复数
public:
      Complex(int r,int i):m_r(r),m_i(i){
   }
      //cout<<c1==>operator<<(cout,c1)	
      friend ostream& operator<<(ostream& os,const Complex& c){
   
        os<<c.m_r<<"+" <<c.m_i<<"i";
	return os;
      }
      //重载+ (成员函数形式)
      //c1+c2 ==>c1.operator(c2)
      const Complex operator+(const Complex& c)const{
   
        Complex res(m_r+c.m_r,m_i+c.m_i);
	return res;
      }
private:
      int m_r;
      int m_i;
};

int main(void){
   
  cout<<add<int>(123,456)<<endl;
  cout<<add<double>(1.23,4.56)<<endl;
  Complex c1(1,2);
  Complex c2(3,4);
  cout<<c1<<","<<c2<<endl;
  cout<<add<Complex>(c1,c2)<<endl;  //4+6i
}

二次编译

在这里插入图片描述
在这里插入图片描述

函数模板的隐式推断

在这里插入图片描述
在这里插入图片描述

参考代码:07deduce.cpp

#include <iostream>
#include <typeinfo>
using namespace std;

template <typename A,typename V>
void func1(A arg){
   
  V var;
  cout <<"调用参数类型:"<<typeid(arg).name()<<endl;
  cout <<"局部变量类型:"<<typeid(var).name()<<endl;
}

template <typename T>
void func2(T x,T y){
   
  cout<<"参数x类型:"<<typeid(x).name()<<endl;
  cout<<"参数y类型: "<<typeid(y).name()<<endl;
}

template <typename T1,typename T2>
T1 func3(T2 x){
   
  T1 y;
  cout <<"参数x类型:"<<typeid(x).name()<<endl;
  cout <<"返回y类型:"<<typeid(y).name()<<endl;
  return y;
}

int main(void){
   
   //func1(100); //error
   func1<int,int>(11); //ok

   //func2(100,1.23); //error
   func2<int>(100,1.23);  //显示推断。隐式转换
   func2<double>(100,1.23);

   func2(100,(int)1.23) ; //显示转换,隐式推断
   func2((double)100,1.23);

   //double d = func3(100); //error
   double d = func3<double>(100); //显式指明返回类型,隐式推断参数类型
}

在这里插入图片描述

函数模板的重载

在这里插入图片描述
参考代码:07overload.cpp

#include <iostream>
#include <typeinfo>
using namespace std;

template <typename T>
void func(T x, T y){
    //针对两个任意类型的数据:约束性一般
        cout<<"func(1),type="<<typeid(T).name()<<endl;
}
template <typename T>
void func(T* x,T* y){
   
   cout<<"func(2),type="<<typeid(T).name()<<endl;
}
int main(void){
   
  int a = 10,b = 20;
  func(a,b) ;  //func(1) ,T = int
  func(&a,&b); //func(2),T = int
  func<int*>(&a,&b);  //func(1) ,T= int*
  return 0;
}

参考代码2: 08overload.cpp

#include <iostream>
#include <typeinfo>
using namespace std;

template <typename T>
void func(T x, T y){
    //针对两个任意类型的数据:约束性一般
	cout<<"func(1),type="<<typeid(T).name()<<endl; 
}
template <typename T>
void func(T* x,T* y){
   
   cout<<"func(2),type="<<typeid(T).name()<<endl;
}

void func(const char* x,const char* y){
    //针对性两个const char *:约束性更强
  cout<<"func(3),type="<<typeid(x).name()<<endl;
}

int main(void){
   
  int a = 10,b = 20;
  func(a,b) ;  //func(1) ,T = int
  func(&a,&b); //func(2),T = int
  func<int*>(&a,&b);  //func(1) ,T= int*

  const char* s1 = "123";
  const char* s2 = "456";
  func(s1,s2); //func(3);
  func<>(s1,s2);  //func(2)
  //如果匹配func(2),类型实参const char*,调用参数类型应该式const char**,无法和调用实参s1,s2
  //相匹配,所以只能选中第一个版本
  func<const char*>(s1,s2); //func(1)


  return 0;
}

在这里插入图片描述

类模板的定义

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

类模板的使用

在这里插入图片描述

类模板的实例化

在这里插入图片描述

类模板中的成员函数

在这里插入图片描述

参考代码:09ct.cpp

 #include <iostream>
using namespace std;

template <typename T>
class Compare{
    //类模板
public:
	Compare(T x,T y):m_x(x),m_y(y){
   }
	T max(void) const{
   
           return m_x < m_y ? m_y:m_x;	
	}
	T min(void) const {
   
           //return m_x >m_y ?m_y:m_x;        	
           //对于类模板的设计者,应该尽可能减少对类型实参的要求,方便类模板的使用者
           return m_x < m_y ? m_x:m_y;	
	}
private:
	T m_x;
	T m_y;
};

class Integer{
   
public:
	Integer(int data):m_data(data){
   }
	friend ostream& operator<<(ostream& os,const Integer& i){
   
           os<<i.m_data;
           return os;	   
	}
	//重载《成员函数形式》
	bool operator<(const Integer& i) const{
   
           return m_data<i.m_data;	
	}
	//重载>(成员函数形式)
	bool operator >(const Integer& i) const{
   
           return m_data>i.m_data;	
	}
private:
	int m_data;
};

int main(void){
   
	//先结合<int>实例化具体的类,再使用该类实例化ci对象
  //Compare<int> ci(123,456);
  //cout<<"max="<<ci.max()<<",min="<<ci.min()<<endl;
  //Compare<double> cd(1.23,4.56);
  //cout<<"max="<<cd.max()<<",min="<<cd.min()<<endl;

  //cout<<sizeof(Compare)<<endl; //error
  //cout<<sizeof(Compare<int>)<<endl;  //ok ,8

  //Compare cc('A','B');  //error
  //Compare<int>ci(123,456);
  //cout<<"max="<<ci.max()<<",min="<<ci.min()<<endl;
  Integer i1(123);
  Integer i2(456);
  Compare<Integer>cInt(i1,i2);//ok
  cout<<"max="<<cInt.max()<<endl;

  return 0;
}

类模板的静态成员

在这里插入图片描述
参考代码:static.cpp

#include <iostream>
using namespace std;

template <typename T>
class A{
   
public:
	void printAddr(void){
   
           cout<<"&m_data:"<<&m_data<<",s_data="<<&s_data<<endl;
	}
private:
	int m_data;  //普通成员变量
	static int s_data; //静态成员便利
};

template <typename T>
int A<T>::s_data; //定义

int main(void){
   
  A<int> i1,i2;
  A<double> d1,d2;
  //一共有几个m_data(4)个?s_data?(2个
  i1.printAddr();
  i2.printAddr();
  d1.printAddr();
  d2.printAddr();
  
}

类模板的递归实例化

在这里插入图片描述
在这里插入图片描述

参考代码:

#include <iostream>
using namespace std;

template <typename T>
class Array{
   
public:
	//下标操作符重载
       T& operator[](size_t i){
   
          return m_a[i] ;
       }
       const T& operator[] (size_t i)const{
   
          return m_a[i] ;
       }
       //获取容器中元素个数
       size_t size(void)const{
   
          return sizeof(m_a)/sizeof(m_a[0]);
       }


       //重载<<
       friend ostream& operator<<(ostream& os,const Array& arr){
   
          for(size_t i=0;i<arr.size();i++) {
   
	     os<<arr[i] <<' ';
	  }
	  return os;
       }

private:
	T m_a[3];
};
int main(void){
   
  Array<int>a1;
  a1[0] = 10;
  a1[1] = 20;
  a1[2] = 30;
  cout<<a1<<endl;
  Array<int>a2;
  a2 = a1;
  cout<<a2<<endl;
  //递归实例化:用类模板实例化的类型,作为类型实参,再实例化该类模板自身
  Array<Array<int> >aa;//二维数组
  for(size_t i=0;i<aa.size();i++)
	  for(size_t j=0;j<aa[i].size();j++)
		  aa[i][j] = i*3+j+1; //1 2 3 4 5 6 7 8 9 
  for(size_t i=0;i<aa.size();i++){
   
     cout<<aa[i] <<endl;
  }
  return 0;
}

类模板的特化

在这里插入图片描述

全类特化

在这里插入图片描述
参考代码:

#include <iostream>
#include <cstring>
using namespace std;

template <typename T>
class Compare{
   
public:
    Compare(T x,T y):m_x(x),m_y(y){
   }
    T Max(void){
   
       cout<<"通用版本" <<endl;
       return m_x<m_y?m_y:m_x;
    }

private:
    T m_x;
    T m_y;
};
template <>
class Compare<char *>{
    //全类特化(针对char *实例化的具体类)
public:
	Compare(char *x,char *y):m_x(x),m_y(y){
   }
	char *Max(void){
   
	   cout<<"特化版本"<<endl;
           return strcmp(m_x,m_y)<0?m_y:m_x;	
	}
private:
    char *m_x;
    char* m_y;
};

int main(void){
   
  Compare<int> cInt(123,456);
  cout<<cInt.Max()<<endl; //456

  char s1[] = "world";
  char s2[] = "hello";
  Compare<char *>cChar(s1,s2);
  cout<<cChar.Max()<<endl; //world

  return 0;
}

成员特化

在这里插入图片描述
参考代码:

#include <iostream>
#include <cstring>
using namespace std;

template <typename T>
class Compare{
   
public:
    Compare (T x,T y):m_x(x),m_y(y){
   }
    T Max(void)const{
   
       cout<<"通用版本" <<endl;
       return m_x<m_y?m_y:m_x;
    }

private:
    T m_x;
    T m_y;
};
template<>
char *Compare<char *>::Max(void)const{
    //成员特化(针对char* 重写的Max函数)
  cout<<"特化版本"<<endl;
  return strcmp(m_x,m_y)<0?m_y:m_x;
}

int main(void){
   
  Compare<int> cInt(123,456);
  cout<<cInt.Max()<<endl; //456

  char s1[] = "world";
  char s2[] = "hello";
  Compare<char *>cChar(s1,s2);
  cout<<cChar.Max()<<endl; //world

  return 0;
}

局部(偏)特化

在这里插入图片描述
在这里插入图片描述

模板的使用技巧

在这里插入图片描述

类模板参数的缺省值

在这里插入图片描述
参考代码:

#include <iostream>
#include <typeinfo>
using namespace std;

template<typename A=double,typename B=A>
class X{
   
public:
	static void foo(void){
   
            cout<<typeid(A).name()<<","<<typeid(B).name()<<endl;	
	}
};

template<typename A=int,typename B=double>
void fun(void){
   
	cout<<typeid(A).name()<<","<<typeid(B).name()<<endl;
}

int main(void){
   
  X<int,int>::foo();
  X<int>::foo();
  X<double>::foo();
  X<>::foo();

  return 0;
}

数值型模板参数(非类型参数)

在这里插入图片描述
参考代码

#include <iostream>
using namespace std;

template<typename T,size_t S=10/*数值型模板参数*/>
class Array{
   
public:
    T& operator[](size_t i){
   
       return m_arr[i] ;
    }
    const T& operator[](size_t i)const{
   
       return m_arr[i] ;
       return const_cast<Array&>(* this) [i];
    }
    size_t size(void) const{
   
      return sizeof(m_arr)/sizeof(m_arr[0] );
    }
    friend ostream& operator<<(ostream& os,const Array& arr){
   
       for(size_t i=0;i<arr
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值