1、概述
(1)What(什么是模板、泛型编程)
模板:
模板分为函数模板和类模板,其类内部的类型和函数的形参类型不具体指定,用一个 虚拟的类型来代表,在具体使用的时候在具体化
泛型编程:
以一种独立于任何特定类型的方式编写代码,模板是泛型编程的基础
(2)Why(模板的作用)
实现代码的重用
(3)Which(有哪些模板)
- 模板函数
- 模板类
(4)模板参数
A.What(什么是模板参数)
模板参数是在 C++ 模板中使用的类型或非类型实体的占位符,分为类型模板参数和非 类型模板参数
B.How(如何使用模板参数)
cpp
template <typename T> T calc(const T&, const T&); //模板的声明
注意:通常一个文件所有模板的声明放在文件的开始位置
C.模板参数的类型成员
- T::value_type():必须显式地告诉编译器该名字是一个类型,且只能使用关键字 typename(而非 class)
D.默认模板参数
与函数默认实参一样,对于一个模板参数,只有当它的右侧都有默认参时,它才可以有默认参数
2、模板函数
带有模板参数的函数,被称为模板函数
cpp
#include <sstream>
using namespace std;
template <class T>//T 是类型模板参数
string tTostring(T t)
{
std::ostringstream osstream;
osstream << t;
return osstream.str();
}
template <typename T, typename U>//模板参数列表
auto add(T t, U u){
if constexpr (std::is_same<T, std::string>::value)
return t + tTostring(u);
if constexpr (std::is_same<U, std::string>::value)
return tTostring(t) + u;
if constexpr (std::is_arithmetic<T>::value && std::is_arithmetic<U>::value)
return t + u;
}
3、模板类
带有模板参数的类被称为模板类
cpp
template <class T>
class Blob {
public:
typedef typename std::vector<T>::size_type size_type;
private:
std::vector<T> *data_;
void check(size_type i, const std::string &msg) const;
public:
Blob()
{
data_ = new std::vector<T>();
}
Blob(std::initializer_list<T> il)
{
data_ = new std::vector<T>(il);
}
Blob(const Blob &blob)
{ //在一个类模板作用域内,可直接使用模板名,而不必指定模板参数
data_ = new std::vector<T>(*blob.getData());
// 也可 blob.data_,在类的成员函数内部,可直接访问同类的其他对象私有成员
}
~Blob()
{
delete data_;
}
std::vector<T> *getData() const
{
return data_;
}
size_type size() const
{
return data_->size();
}
bool empty() const
{
return data_->empty();
}
void push_back(const T &t)
{
data_->push_back(t);
}
void push_back(T &&t)
{
data_->push_back(std::move(t));
}
};
void main()
{
Blob<double> blob; //实例化一个blob对象,用域处理double类型的数据
...
}
(2)成员模板
本身是模板函数的成员函数,成员模板不能是虚函数