【C++】詳解C++的模板

目錄

概念

?編輯

?語法

函數模板

類模板

?非類型模板參數

模板的特化

函數模板特化

類模板特化

全特化

偏特化

分離編譯


概念

模板是C++中非常厲害的設計,模板把通用的邏輯剝離出來,讓不同的數據類型可以復用同一種模板的邏輯,甚至可以讓不同的邏輯復用同一種模板邏輯(仿函數的設計)

【C++】詳解STL的適配器容器之一:優先級隊列 priority_queue-CSDN博客

模板可以幫助我們實現代碼的重用和泛化,提高代碼的靈活性和可維護性。

STL的容器就是對模板很好的運用,可參考

【C++】詳解STL容器之一的 vector-CSDN博客

【C++】詳解STL的容器之一:list-CSDN博客

?語法

template <typename T> //可以寫成template <class T> 
class MyClass {// ...
};template <typename T> //可以寫成template <class T> 
T add(T a, T b) {return a + b;
}

在上面的示例中,MyClass 是一個類模板,add 是一個函數模板。通過使用 typename class 關鍵字聲明模板參數T 就是未知類型

函數模板

通過使用函數模板,我們可以定義一種通用的函數,可以根據實際需要傳不同的數據復用函數模板

函數模板的語法格式如下

template <typename T>
返回類型 函數名(參數列表) {// 函數體
}

其中,template關鍵字表示這是一個函數模板,<typename T>表示定義了一個類型參數T,可以根據需要使用不同的類型來替換T返回類型表示函數的返回類型,函數名表示函數的名稱,參數列表表示函數的參數列表。

在函數模板中,可以使用類型參數T作為函數的參數類型、返回類型或局部變量的類型。例如:

template <typename T>
T max(T a, T b) {return (a > b) ? a : b;
}

上述代碼定義了一個函數模板max,它接受兩個參數a和b,這兩個參數的類型都是T,并且返回類型也是T

使用函數模板時,需要在函數名后面加上尖括號<>,并在其中指定具體的類型。例如:

int result1 = max<int>(3, 5); // 使用int類型實例化函數模板
double result2 = max<double>(3.14, 2.71); // 使用double類型實例化函數模板

max<int>表示使用`int`類型實例化max函數模板,max<double>表示使用double類型實例化max函數模板。傳不同的參數示例化的函數是不同的

函數模板還可以有多個類型參數,可以使用逗號分隔它們。例如:

template <typename T1, typename T2>
void printPair(T1 a, T2 b) {cout << "(" << a << ", " << b << ")" << endl;
}

使用函數模板時,需要指定每個類型參數的具體類型。例如:

printPair<int, double>(3, 3.14); // 使用int和double類型實例化函數模板

在上述代碼中,printPair<int, double>表示使用int類型和double類型實例化printPair函數模板。

總結起來,函數模板是一種通用的函數定義,可以用于多種不同類型的參數。通過使用函數模板,可以編寫一次代碼,然后在不同的地方使用不同的數據類型進行調用。

類模板

通過使用類模板,我們可以定義一種通用的類模板,可以根據實際需要在不同場景下傳入不同的類型實例化出不同的類。

類模板的語法格式如下:

template <typename T> //可以寫成template <class T>
class 類名 {// 成員變量和成員函數的定義
};

在類模板中,可以使用類型參數T作為成員變量的類型、成員函數的參數類型或返回類型。例如:

template <typename T>
class Stack {
private:T* data;int size;
public:Stack(int capacity) {data = new T[capacity];size = 0;}void push(T value) {data[size++] = value;}T pop() {return data[--size];}
};

上述代碼定義了一個類模板Stack,它有一個私有成員變量data和size,分別表示存儲數據的數組和當前棧的大小。類模板還有兩個公有成員函數push和pop,分別用于向棧中壓入元素和彈出棧頂元素。

使用類模板時,需要在類名后面加上尖括號<>,并在其中指定具體的類型。例如:

Stack<int> intStack(10); // 使用int類型實例化類模板
Stack<double> doubleStack(5); // 使用double類型實例化類模板

不然會報如下錯誤

Stack<int>表示使用int類型實例化Stack類模板,Stack<double>表示使用double類型實例化Stack類模板。根據實際的類型參數,編譯器會生成相應的類定義。

類模板還可以有多個類型參數,可以使用逗號分隔它們。例如:

template <typename T1, typename T2>
class Pair {
private:T1 first;T2 second;
public:Pair(T1 a, T2 b) {first = a;second = b;}void print() {cout << "(" << first << ", " << second << ")" << endl;}
};

使用類模板時,需要指定每個類型參數的具體類型。例如:

Pair<int, double> p1(3, 3.14); // 使用int和double類型實例化類模板
Pair<string, int> p2("Hello", 5); // 使用string和int類型實例化類模板

?非類型模板參數

模板參數分為:類型形參非類型形參
類型形參:出現在模板參數列表中,跟在class或者typename之類的參數類型名稱
非類型形參:就是用一個常量作為類(函數)模板的一個參數,在類(函數)模板中可將該參數當成常量來使用
// 定義一個模板類型的靜態數組template<class T, size_t N = 10>class array{public:T& operator[](size_t index){return _array[index];}const T& operator[](size_t index)const{return _array[index];}size_t size()const{return _size;}bool empty()const{return 0 == _size;}private:T _array[N];size_t _size;};
浮點數、類對象以及字符串是不允許作為非類型模板參數的
非類型的模板參數必須在編譯期就能確認結果

模板的特化

概念:

在原模板類的基礎上,針對特殊類型所進行特殊化的實現方式。模板特 化中分為函數模板特化與類模板特化

函數模板特化

必須要先有一個基礎的函數模板
關鍵字 template 后面接一對空的尖括號 <>
函數名后跟一對尖括號,尖括號中指定需要特化的類型
函數形參表 :? 必須要和模板函數的基礎參數類型完全相同
// 函數模板 -- 參數匹配
template<class T>
bool Less(T left, T right)
{return left < right;
}
// 對Less函數模板進行特化
template<>
bool Less<Date*>(Date* left, Date* right) //Date是日期類
{return *left < *right;
}

下面是測試

關于日期類小編也寫了一篇文章:【C++】如何用C++寫一個日期計算器-CSDN博客

類模板特化

全特化

全特化即是將模板參數列表中所有的參數都確定化
template<class T1, class T2>
class Data
{
public:Data() {cout<<"Data<T1, T2>" <<endl;}
private:T1 _d1;T2 _d2;
};
template<>
class Data<int, char>
{
public:Data() {cout<<"Data<int, char>" <<endl;}
private:int _d1;char _d2;
};

下面是測試

偏特化

任何針對模版參數進一步進行條件限制設計的特化版本
偏特化有以下兩種表現方式:
部分特化 ? ?
特化一部分參數
下面是測試代碼
template<class T1, class T2>
class Data
{
public:Data() {cout<<"Data<T1, T2>" <<endl;}
private:T1 _d1;T2 _d2;
};
template <class T1>
class Data<T1, int>
{
public:Data() {cout<<"Data<T1, int>" <<endl;}
private:T1 _d1;int _d2;
};
限制參數
偏特化并不僅僅是指特化部分參數,而是針對模板參數更進一步的條件限制所設計出來的一個特化版本
下面是測試代碼
template<class T1, class T2>
class Data
{
public:Data() {cout<<"Data<T1, T2>" <<endl;}
private:T1 _d1;T2 _d2;
};
//兩個參數偏特化為指針類型
template <typename T1, typename T2>
class Data <T1*, T2*>
{ 
public:Data() {cout<<"Data<T1*, T2*>" <<endl;}private:
T1 _d1;T2 _d2;
};
//兩個參數偏特化為引用類型
template <typename T1, typename T2>
class Data <T1&, T2&>
{
public:Data(const T1& d1, const T2& d2): _d1(d1), _d2(d2){cout<<"Data<T1&, T2&>" <<endl;}private:const T1 & _d1;const T2 & _d2; };

分離編譯

下面了解即可

C/C++程序要運行要經歷以下步驟

預處理--->?編譯---> 匯編---> 鏈接

預處理:將頭文件展開

編譯:頭文件不參與編譯,編譯主要是檢查語法錯誤,多個源文件單獨分開編譯

匯編:將文本文件翻譯成二進制文件

鏈接:將多個編譯好的源文件合成一個

如果將模板聲明和定義分離會報鏈接錯誤

可參考下面這位大佬的文章

為什么C++編譯器不能支持對模板的分離式編譯-CSDN博客

?將聲明和定義放到一個文件 "xxx.hpp" 里面或者xxx.h其實也是可以的。推薦使用這種
?模板定義的位置顯式實例化。這種方法不實用,不推薦使用

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/12296.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/12296.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/12296.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Flutter 中的 DataTable 小部件:全面指南

Flutter 中的 DataTable 小部件&#xff1a;全面指南 在Flutter的Material組件庫中&#xff0c;DataTable是一個用于展示數據的表格組件&#xff0c;它允許開發者以一種結構化和可滾動的方式展示數據集。DataTable非常適合展示詳細信息&#xff0c;如表格數據、統計數據或配置…

PHP黑魔法之md5繞過

php本身是一種弱語言,這個特性決定了它的兩個特點: 輸入的參數都是當作字符串處理變量類型不需要聲明,大部分時候都是通過函數進行類型轉化php中的判斷有兩種: 松散比較:只需要值相同即可,類型不必相同,不通類型比較會先轉化為同類型,比如全數字字符串和數字比較,會比…

凸優化理論學習三|凸優化問題(一)

系列文章目錄 凸優化理論學習一|最優化及凸集的基本概念 凸優化理論學習二|凸函數及其相關概念 文章目錄 系列文章目錄一、優化問題&#xff08;一&#xff09;標準形式的優化問題&#xff08;二&#xff09;可行點和最優點&#xff08;三&#xff09;局部最優點&#xff08;四…

《Python編程從入門到實踐》day28

# 昨日知識點回顧 安裝Matplotlib 繪制簡單的折線圖 # 今日知識點學習 15.2.1 修改標簽文字和線條粗細 # module backend_interagg has no attribute FigureCanvas. Did you mean: FigureCanvasAgg? # 解決辦法&#xff1a;matplotlib切換圖形界面顯示終端TkAgg。 #…

使用Three.js繪制快速而逼真的水

本文將利用GPUComputationRenderer來實現水波紋的繪制&#xff0c;相似的案例可以看threejs官方的GPGPU Water示例。更多精彩內容盡在數字孿生平臺。 什么是 GPGPU GPGPU代表通用圖形處理單元&#xff08;General-Purpose Graphic Processing Unit&#xff09;&#xff0c;意思…

1146 -Table ‘performance schema.session variables‘ doesn‘t exist的錯誤解決

一、問題出現 今天在本地連數據庫的時候&#xff0c;發現這個問題&#xff0c;哎呦我擦&#xff0c;差點嚇死了 二、解決辦法 1&#xff09;找文件 用everything搜一下MySQL Server 5.7 然后去Windows服務找一下MySQL配置文件的具體路徑 如果知道那最好&#xff0c;不知道那…

寶塔8.1.0去除綁定用戶

非要綁定手機號&#xff0c;確實很煩 1&#xff0c;/www/server/panel/BTPanel __init__.py if not public.is_bind():return redirect(/bind, 302) 將is_bind的路由全部注釋 2&#xff0c;/www/server/panel/class下 panelPlugin.py 注釋異常&#xff0c; 新增 softLis…

SSL協議

SSL 安全傳輸協議&#xff08;安全套接層&#xff09; 也叫TLS ---- 傳輸層安全協議 SSL的工作原理&#xff1a;SSL協議因為是基于TCP協議工作的&#xff0c;通信雙方需要先建立TCP會話。因為SSL協議需要進行安全保證&#xff0c;需要協商安全參數&#xff0c;所以也需要建立…

【MySQL】7.MySQL性能優化的六大核心策略

數據庫的性能對整個應用的響應速度和用戶體驗起著至關重要的作用。MySQL&#xff0c;作為廣泛使用的開源關系型數據庫&#xff0c;提供了豐富的性能優化手段。從資源優化、查詢優化到結構、配置、代碼乃至架構優化&#xff0c;每一個層面的調整都可能帶來性能的飛躍。本文將深入…

springboot房屋租賃系統

摘要 房屋租賃系統&#xff1b;為用戶提供了一個房屋租賃系統平臺&#xff0c;方便管理員查看及維護&#xff0c;并且可以通過需求進行設備信息內容的編輯及維護等&#xff1b;對于用戶而言&#xff0c;可以隨時進行查看房屋信息和合同信息&#xff0c;并且可以進行報修、評價…

清理緩存簡單功能實現

在程序開發中&#xff0c;經常會用到緩存&#xff0c;最常用的后端緩存技術有Redis、MongoDB、Memcache等。 而有時候我們希望能夠手動清理緩存&#xff0c;點一下按鈕就把當前Redis的緩存和前端緩存都清空。 功能非常簡單&#xff0c;創建一個控制器類CacheController&#xf…

SpringBoot PowerMockito 私有/靜態/方法/屬性

SpringBoot PowerMockito 私有/靜態/方法/屬性 1 PrepareForTest2 待測試類3 測試類 1 PrepareForTest PrepareForTest 是 PowerMockito 提供的一個注解&#xff0c;用于告訴 PowerMockito 哪些類需要被修改以允許使用 PowerMockito 的功能。 PowerMockito 主要用于修改 Java…

【計算機畢業設計】基于SSM+Vue的線上旅行信息管理系統【源碼+lw+部署文檔+講解】

目錄 1 緒論 1.1 研究背景 1.2 設計原則 1.3 論文組織結構 2 系統關鍵技術 2.1JSP技術 2.2 JAVA技術 2.3 B/S結構 2.4 MYSQL數據庫 3 系統分析 3.1 可行性分析 3.1.1 技術可行性 3.1.2 操作可行性 3.1.3 經濟可行性 3.1.4 法律可行性 3.2系統功能分析 3.2.1管理員功能分析 3.2.…

JavaScript精粹(一)

JavaScript&#xff08;簡稱為JS&#xff09;是一種廣泛應用于網頁開發的腳本語言&#xff0c;具有以下幾個主要作用&#xff1a; 網頁交互&#xff1a;JavaScript 可以用于創建動態的網頁效果&#xff0c;例如響應用戶的操作&#xff0c;實現頁面內容的動態更新&#xff0c;以…

Java SE vs Java EE:深入剖析及面試指南

Java 平臺提供了多個版本來滿足不同應用場景的需求&#xff0c;其中最常用的是 Java SE&#xff08;Standard Edition&#xff09;和 Java EE&#xff08;Enterprise Edition&#xff09;。理解這兩個版本的區別對于任何 Java 開發者都是至關重要的&#xff0c;尤其是在面試過程…

C++字符串細節,面試題06

文章目錄 22. 字符串22.1. 字符數組 vs 字符指針 vs 常量字符指針 vs string22.2. strcpy vs sprintf vs memcpy22.3. strlen vs length vs size vs sizeof22.4. 字符串之間的轉換22.5 其他數據類型與字符串之間的轉換22.6 字符串分割 22. 字符串 22.1. 字符數組 vs 字符指針 …

Spring整合其他技術

文章目錄 Spring整合mybatis思路分析Mybatis程序核心對象分析整合Mybatis 代碼實現 Spring整合Junit修改成警告 Spring整合mybatis 思路分析 Mybatis程序核心對象分析 上面圖片是mybatis的代碼&#xff0c;上述有三個對象&#xff0c;分別是sqlSessionFactory&#xff0c;sqlS…

Linux:配置客戶端自定義autofs服務

Linux&#xff1a;配置客戶端自定義autofs服務 修改autofs的主策略文件 [rootserver200 data]# vim /etc/auto.master# 修改內容如下 /misc /etc/auto.misc # 掛載目錄的上級目錄 /mnt /etc/auto.timinglee --timeout3修改autofs的自定義策略文件 [rootserver200 data]…

數據庫SQL編寫規范-SQL書寫規范整理(SQL語句書寫規范全解-Word原件)

編寫本文檔的目的是保證在開發過程中產出高效、格式統一、易閱讀、易維護的SQL代碼。 1 編寫目 2 SQL書寫規范 3 SQL編寫原則 軟件全套精華資料包清單部分文件列表&#xff1a; 工作安排任務書&#xff0c;可行性分析報告&#xff0c;立項申請審批表&#xff0c;產品需求規格說…

鴻蒙布局Column/Row/Stack

鴻蒙布局Column/Row/Stack 簡介我們以Column為例進行講解1. Column({space: 10}) 這里的space: 10&#xff0c;表示Column里面每個元素之間的間距為102. width(100%)&#xff0c;height(100%) 表示寬高占比3. backgroundColor(0xffeeeeee) 設置背景顏色4. padding({top: 50}) 設…