C++函数模板

一、函数模板的定义

函数模板的定义和声明放在一起,前面需要加一行:

template<typename T1 ,...... ,typename TN>

T表示类型待定,我们在使用模板时需要明确类型。
模板标识从template开始定义,后续跟着一对“<>”,中间是参数列表。模板参数表示等待绑定实际类型的模板类型列表,统一表示为“typename”类型,或者是“class”类型。
注意1、一旦声明了template,则后续模板参数列表不能为空。
注意2、模板参数列表,可以指定函数参数类型,也可以指定返回值类型,也可以指定函数局部变量类型。
一个典型的使用实例:

#include <iostream>
using namespace std;

class Student{
private:
    string name;
public:
    Student(string name){
        this->name=name;
    }

    void display(){
        cout<<"I am "<<name<<endl;
    }
};

template<typename M>
M f(M m1, M m2){   //模板参数作为函数参数和函数返回值
    if(m1<m2){
        return m1;
    } else{
        return m2;
    }
}

template<typename M>       //模板参数作为局部变量
void f1(){
    M m("Tom");
    m.display();
}

int main(){
    cout<<f(1,2)<<endl;
    cout<<f(1.2,3.2)<<endl;
    string a="abc";
    string b="abd";
    cout<<f(a,b)<<endl;
    cout<<f('a','b')<<endl;

    f1<Student>();
    return 0;
}

输出:

1
1.2     
abc     
a       
I am Tom

这里有个小坑,比较字符串大小时候,如果这么写:

#include <iostream>
using namespace std;
template<typename M>
int f(M m1, M m2){
    if(m1<m2){
        return 1;
    } else{
        return -1;
    }
}
int main(){
    cout<<f("abc","abd")<<endl;
    return 0;
}

可能会有问题。因为“abc”底层是指针,我当成string用,是因为string有对应的转换构造函数。这是模板,编译器不知道应该转换为什么类型,所以不会调用转换构造函数,直接是两个地址比较大小。

注意:函数模板定义,模板参数不能为空。

二、函数模板的具体化

有如下原则:
(1)用户使用时,必须告诉编译器,每一个模板参数实例化为某一个类型。
(2)可以显示指定类型,如下:

cout<<f<int>(1,2)<<endl;

也可以不显示指定,隐式通过传入的类型让编译器推断。

(3)可以显示指定与隐式指定同时进行,但是要注意,显示指定的类型是按序匹配。

三、模板的编译

(1)编译器看到模板的时候,不进行编译,而是在使用(实例化)的时候才进行编译。
(2)模板函数的声明和定义都放到头文件中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值