2020-08-28

在类外定义成员函数。在类外定义成员函数时仍然需要带上模板头。
类模板在实例化时必须显式地指明数据类型,编译器不能根据给定的数据推演出数据类型。
而对于函数模板,调用函数时可以不显式地指明实参(也就是具体的类型)
这种通过函数实参来确定模板实参(也就是类型参数的具体类型)的过程称为模板实参推断。
对于函数模板,类型转换则受到了更多的限制,仅能进行「const 转换」和「数组或函数指针转换」,其他的都不能应用于函数模板。
当函数形参是引用类型时,数组不会转换为指针

模板所支持的类型是宽泛的,没有限制的,我们可以使用任意类型来替换,这种编程方式称为泛型编程(Generic Programming)。

交换两个数组唯一的办法就是逐个交换所有的数组元素

C++ 允许对函数模板进行重载,程序员可以像重载常规函数那样重载模板定义。

显式地指明实参时可以应用正常的类型转换

函数模板显示具体化

//函数模板
template<class T> const T& Max(const T& a, const T& b);
//函数模板的显示具体化(针对STU类型的显示具体化)
template<> const STU& Max<STU>(const STU& a, const STU& b);
显示具体化优先于常规模板,而非模板函数优先于显示具体化和常规模板。

类具体化

当在类的外部定义成员函数时,普通类模板的成员函数前面要带上模板头,而具体化的类模板的成员函数前面不能带模板头。
部分显示具体化(只能用于类),和具体显示化一样,没有被具体化的类型参数需要
emplate<typename T2>  //这里需要带上模板头
void Point<char*, T2>::display() const{
    cout<<"x="<<m_x<<" | y="<<m_y<<endl;
}

在函数模板中使用非类型参数

交换数组内容
template<typename T, unsigned N> void Swap(T (&a)[N], T (&b)[N]){
    T temp;
    for(int i=0; i<N; i++){
        temp = a[i];
        a[i] = b[i];
        b[i] = temp;
    }
}
T (&a)[N]表明 a 是一个引用,它引用的数据的类型是T [N],也即一个数组

非类型参数的限制

当非类型参数是一个整数时,传递给它的实参,或者由编译器推导出的实参必须是一个常量表达式
非类型参数是一个指针(引用)时,绑定到该指针的实参必须具有静态的生存期;换句话说,实参必须存储在虚拟地址空间中的静态数据区。局部变量位于栈区,动态创建的对象位于堆区,它们都不能用作实参。

通过类模板创建对象时并不会实例化所有的成员函数,只有等到真正调用它们时才会被实例化;如果一个成员函数永远不会被调用,那它就永远不会被实例化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值