模板参数,模板分离编译

模板的形参:

1.类型形参:

template<class T>
void h(T a) 
{//……}

  •  类型形参是指:class T/ typename T中的T,类型形参的名字由用户自己定义,模板的形参(T)表示一个未知的类型。
  • 模板类型形参可以作为类型说明符用在模板中的任何地方,与内置类型/类类型的使用方式完全相同,即可以用于指定返回类型,声明变量等地方 
  • 不能为同一个的模板类型形参指定两种不同的类型,比如:
template<class T> 
void h(T a,T b) 
{} 
void test() 
{
     h(1,1.2); 
}

这样的调用方式会出错,因为该语句给同一模板形参T指定了俩种不同的类型(int,double)

  • 无论时模板函数,还是模板类都不能给同一个模板类型指定俩者不同类型的形参 

2.非类型模板形参:

  • 模板的非类型形参也就是内置类型形参:如:template<class T,int a>class B{},其中int a就是非类型模板形参
  • 非类型模板形参在模板定义的内部是常量值
  • 非类型模板形参只能是整型,指针,引用,不能使用double,string等
  • 调用非类型模板形参的实参只能是一个常量表达式,即他必须能在编译时计算出结果
  • 任何局部对象,局部变量,局部对象地址,局部变量地址都不是常量表达式,都不能用作非类型模板形参的实参。全局指针,全局变量,全局对象也不是一个常量表达式,不能用作非类型模板形参的实参
  • 全局变量的地址或引用,全局对象的地址或引用,const类型变量是常量表达式,可以用作非类型模板形参的实参
  • sizeof表达式的结果是一个常量表达式,也能用作非类型模板形参的实参
  • 当模板的形参是整型时调用该函数的实参必须时整型,且在编译期间是常量。比如int b,AA<int ,b> a1;这时编译器就会报错,因为b是一个变量,如果修改为const int b,AA<int ,b> a1;就不会出错,因为此时b是一个常量

非类型模板形参的形参和实参间所允许的转换

  1. 允许从数组到指针,从函数到指针。
template<int *>
class A 
{}; 
void Test() 
{ 
    int b[1]; 
    A<b> a1; 
}

2.const修饰符的转换

template<const int*a> 
class A {}; 
void Test() 
{ 
    int* b; 
    A<&b> a1;//从int* 到const int* 的转换 
}

 

3.提升转换(short——int)

4.整值转换(int ——unsigned int)

 

模板形参总结:

  1. 类型参数:可以给类模板的类型形参提供默认值,但不能给函数模板的类型形参提供默认值。
  2. 非类型参数:函数模板和类模板都可以为类模板的非类型形参提供默认值
  3. 给类模板的类型形参默认值的方式:
    template<class T1,class T2=int>
    class AA{};

     

  4. 类模板的类型参数提供默认值的方式与函数缺省一样,要从右向左,不能给T1提供默认值而不给T2。

  5. 在类模板的外部定义类中的成员时template后的形参表应省略默认的形参类型 

    template <calss T1,class T2 = int>
    class A 
    {
    public:
        void h();
    };
    
    
    viod A<T1,T2>::h()
    
    {}
    
    

     

模板的模板参数:

template<class T>
class Seqlist
{
private:
	int _size;
	int _capacity;
	T* _data;
};

template<class T, template<class>calss Container = Seqlist>
calss Stack
{
public:
	void Push(const T& x);
	void pop();
	const T& Top();

private:
	Container<T> _con;
}

void Test()
{
	Stack<int> s1;
	Stack<int, Seqlist>s2;
}

 

3.模板的分离编译:

解决方法:

  1. 在模板头文件xxx.h里面显示实例化->模板类的定义后面添加template class SeqList<int>;
  2. 一般不推荐这种方法,一方面老编译器可能不支持,另一方面实例化依赖调用者
  3. 将声明和定义放在同一个文件“xxx.hpp”里面,添加使用这种方法 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值