模板與泛型編程
- 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(什么是模板實參推斷)
在實例化模板函數或模板類的時候,進行模板實參推斷