1.函数模板
定义形式:
template <模板参数表>
类型名 函数名(参数表)
{
函数体
}
模板参数表:
class/typename + 标识符
普通变量/常量标识符
class与typename:
class
和 typename
在模板编程中通常是可以互换使用的,但在某些情况下,它们有细微的区别
1.函数模板声明:
template<class T> class MyClass1;
template<typename T> class MyClass2;
2.内部类型声明:
template<typename T>
void foo() {
typename T::InnerType* ptr; // 必须使用 typename
// class T::InnerType* ptr; // 错误,不能使用 class
}
3.成员模板:
template<typename T>
class MyClass {
public:
template<typename U>
void bar() {
typename T::template InnerClass<U> obj; // 必须使用 typename
// class T::template InnerClass<U> obj; // 错误,不能使用 class
}
};
例题
#include<iostream>
using namespace std;
template <typename T>
T abs(T x) {
return x < 0 ? -x : x;
}
int main() {
int n = -5;
double d = -5.5;
// 编译器从实参类型推导出函数模板的类型参数
cout << abs(n) << endl;
cout << abs(d) << endl;
return 0;
}
函数模板与函数的区别:
1.函数模板本身编译时不产生任何代码
2.函数指针只能指向模板实例,不能指向模板
2.类模板
也称:参数化类
语法形式:
template <模板参数表>
class 类名
{
类成员声明
}
在类模板外定义其成员函数
template <模板参数表>
类型名 类名<模板参数标识符列表>::函数名(参数表)
使用一个类模板建立对象
模板名<模板参数表> 对象名;
typedef与using
typedef DemoClass<int>IntDemoClass;
using IntDemoClass=DemoClass<int>;
// 定义模板别名只能用using
例题:
#include<iostream>
#include<cstdlib>
using namespace std;
struct Student {
int id; // 学号
float gpa; // 平均分
};
template <class T>
class Store {
private:
T item;
bool haveValue; // 标记item是否已经存入内容
public:
Store(); // 缺省形式(无形参)构造函数
T& getElem();
void putElem(const T& x);
};
// 成员函数的实现
// 缺省构造函数
template<class T>
Store<T>::Store() :haveValue(false) {}
//提取数据函数
template<class T>
T& Store<T>::getElem() {
// 不能提取未初始化的数据
if (!this->haveValue) {
cout << "No item!" << endl;
exit(1); // 使程序完全退出,返回到操作系统
}
return item;
}
// 存入数据函数
template<class T>
void Store<T>::putElem(const T& x) {
haveValue = true;
item = x;
}
int main() {
Store<int>s1, s2; // 定义两个Store<int>类对象
s1.putElem(3);
s2.putElem(-7);
cout << "s1:" << s1.getElem() << endl;
cout << "s2:" << s2.getElem() << endl;
Student g = { 1000,99 };
Store<Student>s3; // 定义Store<Studemt>对象
s3.putElem(g);
cout << "s3:" << s3.getElem().id << " " << s3.getElem().gpa << endl; // s3.getElem()返回的是一个结构体,不能直接输出
Store<double>d;
cout << d.getElem() << endl; //尝试访问未初始化对象
// exit()使程序完全退出,后面的语句也不执行
cout << "Hello !" << endl;
return 0;
}