模板与泛型编程
- 1、概述
- (1)What(什么是模板、泛型编程)
- (2)Why
- (3)Which
- (4)模板参数
- A.What
- B.How
- C.模板参数的类型成员
- D.默认模板参数
- 2、模板函数
- 3、模板类
- (1)How(如何定义和使用模板类)
- (2)成员模板
- 4、模板实参推断
- (1)What(什么是模板实参推断)
- (2)
- 5、动态内存分配
- 6、智能指针模板
1、概述
(1)What(什么是模板、泛型编程)
模板:
模板分为函数模板和类模板,其类内部的类型和函数的形参类型不具体指定,用一个 虚拟的类型来代表,在具体使用的时候在具体化
泛型编程:
以一种独立于任何特定类型的方式编写代码,模板是泛型编程的基础
(2)Why
实现代码的重用
(3)Which
- 模板函数
- 模板类
(4)模板参数
A.What
模板参数是在 C++ 模板中使用的类型或非类型实体的占位符,分为类型模板参数和非 类型模板参数
B.How
template <typename T> T calc(const T&, const T&); //模板的声明
注意:通常一个文件所有模板的声明放在文件的开始位置
C.模板参数的类型成员
- T::value_type():必须显式地告诉编译器该名字是一个类型,且只能使用关键字 typename(而非 class)
D.默认模板参数
与函数默认实参一样,对于一个模板参数,只有当它的右侧都有默认参时,它才可以有默认参数
2、模板函数
#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、模板类
(1)How(如何定义和使用模板类)
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)成员模板
本身是模板函数的成员函数,成员模板不能是虚函数
4、模板实参推断
(1)What(什么是模板实参推断)
在实例化模板函数或模板类的时候,进行模板实参推断