C++類模板與函數(shù)模板基礎(chǔ)詳細(xì)講解
函數(shù)模板
當(dāng)我們想要定義一個(gè)可以支持泛型的函數(shù)時(shí),就要采用函數(shù)模板的方式了。所謂泛型就是可以支持多種類型的操作,比如我們定義一個(gè)compare操作,他可以根據(jù)傳遞給他的參數(shù)類型動(dòng)態(tài)調(diào)用對(duì)應(yīng)的函數(shù)版本,實(shí)現(xiàn)多種類型的比較。
template <typename T> int compare(const T &v1, const T &v2) { if (v1 < v2) return -1; if (v2 < v1) return 1; return 0; }
比較函數(shù)是一個(gè)模板函數(shù),它支持T類型的對(duì)象比較,模板函數(shù)定義的規(guī)則是用template 聲明模板的類型為T,然后用T做參數(shù)即可。
調(diào)用的規(guī)則傳遞實(shí)參就可以了,前提是實(shí)參的類型要支持比較大小,如果是類的類型我們可以重載比較運(yùn)算符。
int res = compare(3, 4); cout << "compare(3,4) res is " << res << endl; vector<int> v1 = {1, 3, 5}; vector<int> v2 = {2, 4}; res = compare(v1, v2); cout << "compare(v1, v2) res is " << res << endl;
我們分別傳遞了int類型和vector類型的參數(shù)作為compare比較的參數(shù)。模板函數(shù)也支持多個(gè)類型,我們可以再定義一個(gè)支持多個(gè)參數(shù)類型的模板函數(shù)
template <typename T, typename U> int printData(const T &t, const U &u) { cout << "t is " << t << endl; cout << "u is " << u << endl; }
調(diào)用規(guī)則和上邊類似,傳遞兩個(gè)不同類型即可
printData(3.4, "hello world");
模板函數(shù)也支持非參數(shù)類型,用已知類型定義變量
template <unsigned N, unsigned M> int compareArray(const char (&p1)[N], const char (&p2)[M]) { return strcmp(p1, p2); }
compareArray的模板里用了已知類型unsigned定義了兩個(gè)變量N和M。
調(diào)用的時(shí)候N和M會(huì)自動(dòng)根據(jù)實(shí)參獲取值
res = compareArray("hello zack", "nice to meet u"); cout << "compareArray(" << "hello zack " << ", nice to meet u" << ") res is " << res << endl;
M和N就是傳遞的兩個(gè)數(shù)組的長度。
類模板
我們實(shí)現(xiàn)一個(gè)模板類,使其支持類似vector的操作,包括push_back, empty, back, 以及pop_back,取索引[]操作等。
//定義模板類型的blob template <typename T> class Blob { public: typedef T value_type; typedef typename std::vector<T>::size_type size_type; //構(gòu)造函數(shù) Blob() { data = make_shared<std::vector<T>>(); } Blob(std::initializer_list<T> il) { data = make_shared<std::vector<T>>(il); // for (const T &m : il) // { // data->push_back(m); // } } // Blob 中元素?cái)?shù)目 size_type size() const { return data->size(); } bool empty() const { return data->empty(); } //添加和刪除元素 void push_back(const T &t) { data->push_back(t); } //移動(dòng)版本的push_back void push_back(const T &&t) { data->push_back(std::move(t)); } //刪除元素 void pop_back(); //元素訪問 T &back(); T &operator[](size_type i); private: std::shared_ptr<std::vector<T>> data; //校驗(yàn)數(shù)據(jù)是否有效 void check(size_type i, const std::string &msg) const; };
我們?cè)陬愅鈱?shí)現(xiàn)check, pop_back, back, 以及[]操作。
template <typename T> void Blob<T>::check(size_type i, const std::string &msg) const { if (i >= data->size()) throw std::out_of_range(msg); } template <typename T> void Blob<T>::pop_back() { if (data->empty()) { return; } data->pop_back(); } template <typename T> T &Blob<T>::back() { return data->back(); } template <typename T> T &Blob<T>::operator[](size_type i) { check(i, "index out of range"); return (*data)[i]; }
每一個(gè)類的成員函數(shù)在類外實(shí)現(xiàn)時(shí)都要聲明template。
類模板的使用如下
void use_classtemp() { Blob<int> ia; Blob<int> ia2 = {0, 1, 2, 3, 5}; Blob<string> ia3 = {"hello ", "zack", "nice"}; for (size_t i = 0; i < ia2.size(); i++) { ia2[i] = i * i; } for (size_t i = 0; i < ia2.size(); i++) { cout << ia2[i] << endl; } for (size_t i = 0; i < ia3.size(); i++) { string_upper(ia3[i]); } for (size_t i = 0; i < ia3.size(); i++) { cout << ia3[i] << endl; } const auto &data = ia3.back(); cout << data << endl; ia3.pop_back(); const auto &data2 = ia3.back(); cout << data2 << endl; }
總結(jié)
到此這篇關(guān)于C++類模板與函數(shù)模板基礎(chǔ)詳細(xì)講解的文章就介紹到這了,更多相關(guān)C++類模板與函數(shù)模板內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)LeetCode(110.平衡二叉樹)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(110.平衡二叉樹),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C語言實(shí)現(xiàn)經(jīng)典排序算法的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用C語言實(shí)現(xiàn)經(jīng)典排序算法中的冒泡排序、選擇排序、插入排序、希爾排序,文中的示例代碼講解詳細(xì),需要的可以參考一下2022-08-08Qt使用QChart實(shí)現(xiàn)靜態(tài)顯示溫度變化曲線
QChart模塊是Qt?Charts庫的基礎(chǔ),提供了用于創(chuàng)建和顯示各種類型圖表的類和接口,本文主要介紹了如何使用QChart實(shí)現(xiàn)動(dòng)態(tài)顯示3個(gè)設(shè)備的溫度變化曲線,感興趣的可以了解一下2023-06-06