[C++] 模板template

目錄

1、函數模板

1.1 函數模板概念

1.2 函數模板格式

1.3 函數模板的原理

1.4 函數模板的實例化

1.4.1 隱式實例化

1.4.2 顯式實例化

1.5 模板參數的匹配原則

2、類模板

2.1 類模板的定義格式

2.2 類模板的實例化


講模板之前呢,我們先來談談泛型編程:

泛型編程:編寫與類型無關的通用代碼,是代碼復用的一種手段。模板是泛型編程的基礎。
模板分為兩類:函數模板與類模板

1、函數模板

1.1 函數模板概念

函數模板代表了一個函數家族,該函數模板與類型無關,在使用時被參數化,根據實參類型產生函數的特定類型版本。

1.2 函數模板格式

template<typename T1, typename T2,......,typename Tn>
返回值類型 函數名(參數列表){}

//template<class T>
template<typename T>
void Swap(T& left, T& right)
{T tmp = left;left = right;right = tmp;
}

注意:typename是用來定義模板參數關鍵字,也可以使用class(切記:不能使用struct代替class) 。

1.3 函數模板的原理

函數模板是一個藍圖,它本身并不是函數,是編譯器用使用方式產生特定具體類型函數的模具。所以其實模板就是將本來應該我們做的重復的事情交給了編譯器。

在編譯器編譯階段,對于模板函數的使用,編譯器需要根據傳入的實參類型來推演生成對應類型的函數以供調用。比如:當用double類型使用函數模板時,編譯器通過對實參類型的推演,將T確定為double類型,然后產生一份專門處理double類型的代碼,對于字符類型也是如此。

1.4 函數模板的實例化

用不同類型的參數使用函數模板時,稱為函數模板的實例化。模板參數實例化分為:隱式實例化和顯式實例化。

1.4.1 隱式實例化

隱式實例化是讓編譯器根據實參推演模板參數的實際類型

template<class T>
T Add(const T& left, const T& right)
{return left + right;
}
int main()
{int a1 = 10, a2 = 20;double d1 = 10.0, d2 = 20.0;Add(a1, a2);Add(d1, d2);return 0;
}

這里Add(a1, a2)與Add(d1, d2)都是隱式實例化,編譯器會根據實參推出實際類型。

我們再來看一段代碼:

template<class T>
T Add(const T& left, const T& right)
{return left + right;
}int main()
{int i = 1;double d = 1.1;Add(i, d);return 0;
}

該語句不能通過編譯,因為在編譯期間,當編譯器看到該實例化時,需要推演其實參類型通過實參i將T推演為int,通過實參d將T推演為double類型,但模板參數列表中只有一個T,編譯器無法確定此處到底該將T確定為int 或者 double類型而報錯。

注意:在模板中,編譯器一般不會進行類型轉換操作,因為一旦轉化出問題,編譯器就需要背黑鍋Add(i, d);

這里要解決這樣的問題有兩種方式:

1. 用戶自己來強制轉化;

2. 使用顯式實例化。

int main()
{int i = 1;double d = 1.1;Add(i, (int)d);return 0;
}

1.4.2 顯式實例化

顯式實例化是在函數名后的<>中指定模板參數的實際類型

template<class T>
T Add(const T& left, const T& right)
{return left + right;
}
int main()
{int i = 1;double d = 1.1;Add<int>(i, d);// 顯式實例化為intAdd<double>(i, d);// 顯示實例化為doublereturn 0;
}

如果類型不匹配,編譯器會嘗試進行隱式類型轉換,如果無法轉換成功編譯器將會報錯。

1.5 模板參數的匹配原則

1. 一個非模板函數可以和一個同名的函數模板同時存在,而且該函數模板還可以被實例化為這個非模板函數

// 專門處理int的加法函數
int Add(int left, int right)
{return left + right;
}
// 通用加法函數
template<class T>
T Add(T left, T right)
{return left + right;
}
void Test()
{Add(1, 2); // 與非模板函數匹配,編譯器不需要特化Add<int>(1, 2); // 調用編譯器特化的Add版本
}

2. 對于非模板函數和同名函數模板,如果其他條件都相同,在調動時會優先調用非模板函數而不會從該模板產生出一個實例。如果模板可以產生一個具有更好匹配的函數, 那么將選擇模板

// 專門處理int的加法函數
int Add(int left, int right)
{return left + right;
}
// 通用加法函數
template<class T1, class T2>
T1 Add(T1 left, T2 right)
{return left + right;
}
void Test()
{Add(1, 2); // 與非函數模板類型完全匹配,不需要函數模板實例化Add(1, 2.0); // 模板函數可以生成更加匹配的版本,編譯器根據實參生成更加匹配的Add函數 
}

3. 模板函數不允許自動類型轉換,但普通函數可以進行自動類型轉換

2、類模板

2.1 類模板的定義格式

template<class T1, class T2, ..., class Tn>
class 類模板名
{// 類內成員定義
};
template<class T>
class stack
{
public:stack();//聲明,在類外面定義~stack(){delete[] _a;_top = _capacity = 0;}
private:T* _a;int _top;int _capacity;
};// 注意:類模板中函數放在類外進行定義時,需要加模板參數列表
template<class T>
stack<T>::stack(): _a(nullptr), _top(0), _capacity(0)
{}

2.2 類模板的實例化

類模板實例化與函數模板實例化不同,類模板實例化需要在類模板名字后跟<>,然后將實例化的類型放在<>中即可,類模板名字不是真正的類,而實例化的結果才是真正的類

int main()
{stack<int> st1;stack<char> st2;return 0;
}

如果我們的棧是要存儲int類型的數據,我們就實例化為int,如果是存儲char類型的數據,就實例化為char類型。

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

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

相關文章

Qt讀寫Excel--QXlsx編譯為靜態庫2

1、概述&#x1f954; 在使用QXlsx時由于源碼文件比較多&#xff0c;如果直接加載進項目里面&#xff0c;會增加每次編譯的時間&#xff1b; 直接將源碼加載進項目工程中&#xff0c;會導致項目文件非常多&#xff0c;結構變得更加臃腫&#xff1b; 所以在本文中將會將QXlsx編譯…

骨傳導耳機頭暈是怎么回事?骨傳導耳機好不好

骨傳導耳機在音頻傳輸上采用了不同于傳統耳機的方式。它們通過將聲音振動傳遞到顳骨&#xff0c;然后通過骨骼傳導到內耳&#xff0c;從而使用戶能夠聽到音樂或聲音。 然而&#xff0c;有些人在使用骨傳導耳機時可能會感到頭暈。這可能與以下幾個原因有關&#xff1a; 1、剛開…

prometheusalert區分告警到不同釘釘群

方法一 修改告警規則 - alert: cpu使用率大于88%expr: instance:node_cpu_utilization:ratio * 100 > 88for: 5mlabels:severity: criticallevel: 3kind: CpuUsageannotations:summary: "cpu使用率大于85%"description: "主機 {{ $labels.hostname }} 的cp…

99%的Python用戶都不知道的f-string隱秘技巧

f-string想必很多Python用戶都基礎性的使用過&#xff0c;作為Python3.6版本開始引入的特性&#xff0c;通過它我們可以更加方便地向字符串中嵌入自定義內容&#xff0c;但f-string真正蘊含的功能遠比大多數用戶知道的要豐富&#xff0c;今天我們就來一起get它們~ 「最基礎用法…

ajax解析

Ajax&#xff08;Asynchronous JavaScript and XML&#xff09;是一種用于在不重新加載整個頁面的情況下與服務器交換數據的技術。它通過異步的方式發送請求和接收響應&#xff0c;能夠實現在后臺與服務器進行數據交互&#xff0c;然后更新頁面的部分內容&#xff0c;從而提升用…

【CI/CD】基于 Jenkins+Docker+Git 的簡單 CI 流程實踐(上)

基于 JenkinsDockerGit 的簡單 CI 流程實踐&#xff08;上&#xff09; 在如今的互聯網時代&#xff0c;隨著軟件開發復雜度的不斷提高&#xff0c;軟件開發和發布管理也越來越重要。目前已經形成一套標準的流程&#xff0c;最重要的組成部分就是 持續集成 及 持續交付、部署。…

GPU編程基礎-CUDA實現圖像處理

GPU編程基礎-CUDA實現圖像處理 1. 相關基礎概念1.1 Host和Device程序1.2 Kernel程序1.3 SIMT和SIMD1.4 GPU計算的 Occupancy指標1.5 GPU計算的基本流程2. GPU計算框架與過程說明3. 一個基于CUDA的圖像處理例子4. 一些報錯解決1. 相關基礎概念 1.1 Host和Device程序 在CPU上運行…

Effective C++學習筆記(7)

目錄 條款41&#xff1a;了解隱式接口和編譯多態條款42&#xff1a;了解typename的雙重意義條款43&#xff1a;學習處理模板化基類內的名稱條款44&#xff1a;將與參數無關的代碼抽離templates條款45&#xff1a;運用成員函數模板接受所有兼容類型條款46&#xff1a;需要類型轉…

opencv,opengl,osg,vulkan,webgL,opencL,cuda,osg,vtk,ogre的區別

OpenCV OpenCV是一個基于BSD許可&#xff08;開源&#xff09;發行的跨平臺計算機視覺和機器學習軟件庫&#xff0c;可以運行在Linux、Windows、Android和Mac OS操作系統上。 它輕量級而且高效——由一系列 C 函數和少量 C 類構成&#xff0c;同時提供了Python、Ruby、MATLAB等…

avue多選列表根據后端返回的某個值去判斷是否選中;avue-curd多選回顯

效果如上&#xff1a; getSiteList().then(res > {//列表數據this.siteData res.data.datathis.$nextTick(()>{this.siteData.forEach(item>{//業務條件if(item.configid&&item.configid!0&&item.configid>0){//符合條件時調用選中的方法this.$…

JAVASE---數組的定義與使用

數組的基本概念 什么是數組 數組是具有相同類型元素的集合&#xff0c;在內存中連續存儲。 1. 數組中存放的元素其類型相同 2. 數組的空間是連在一起的 3. 每個空間有自己的編號&#xff0c;起始位置的編號為0&#xff0c;即數組的下標 數組的創建及初始化 數組的創建 T[…

mybatis高級特性

文章目錄 數據庫事務管理批處理插件擴展持久化和ORM緩存機制 數據庫事務管理 通過注解方式&#xff1a; 在需要進行事務管理的方法上添加Transactional注解&#xff0c;該注解可以用于類或方法上。在配置文件中開啟事務管理器&#xff0c;并指定事務管理器的類型和連接池等相關…

Java SpringBoot Vue智能停車系統

基礎環境 JDK1.8、Maven、Mysql、IntelliJ IDEA 內置功能 系統管理&#xff1a;角色管理、接口管理、系統菜單、全局配置 賬號管理&#xff1a;用戶管理、合作單位 系統監控&#xff1a;監控大屏、日志監控 財務管理&#xff1a;訂單列表 停車記錄&#xff1a;停車記錄 車輛管…

Labview選項卡之實現被選擇選項卡工作

文章目錄 前言一、使用選項卡二、實現被選擇選項卡工作1、需求2、分析3、實現①、前面板②、程序框圖 三、效果展示四、源碼自取 前言 有些時候&#xff0c;我們做界面&#xff0c;需要好多個界面切換。如果是同一個 VI 里界面切換&#xff0c;一般都是選項卡了。切換不同選項…

使用phpstorm開發調試thinkphp

1.環境準備 1.開發工具下載&#xff1a;PhpStorm: PHP IDE and Code Editor from JetBrains 2.PHP下載&#xff1a;PHP: Downloads 3. PHP擴展&#xff1a;PECL :: Package search 4.用與調試的xdebug模塊&#xff1a; Xdebug: Downloads xdebug模塊&#xff0c;如果是php8以…

23.8.16日總結

原先寫的評論是每級評論用縮進來區分&#xff0c;所以最多設置的是九級評論&#xff0c;修改了排版和格式&#xff1a; 還有管理員頁面&#xff0c;查看文章時可以進行點贊&#xff0c;收藏的操作&#xff0c;現在進行了修改&#xff0c;將相關操作隱藏。 還有點擊查看未發布…

js如何獲取字符串大小是幾M

js如何獲取字符串大小是幾M 在JavaScript中&#xff0c;可以使用以下方法來獲取字符串的大小&#xff08;以字節為單位&#xff09;&#xff1a; function getStringSizeInBytes(str) {// 使用UTF-8編碼計算字符串的字節長度let totalBytes new Blob([str]).size;// 將字節長…

14-矩陣相乘及其運算法則

矩陣與向量的乘法 在這一篇文章中我們就將基于上一篇重新審視矩陣的這個視點來理解矩陣的乘法&#xff0c;那么在這一篇&#xff0c;我們主要來看一下矩陣和向量的乘法。這里這個線性方程組是上一小節給大家舉的模擬的一個非常簡單的小型經濟系統的例子&#xff0c;我們可以把…

文件的導入與導出

文章目錄 一、需求二、分析1. Excel 表格數據導出2. Excel 表格數據導入一、需求 在我們日常開發中,會有文件的導入導出的需求,如何在 vue 項目中寫導入導出功能呢 二、分析 以 Excel 表格數據導出為例 1. Excel 表格數據導出 調用接口將返回的數據進行 Blob 轉換,附: 接…

logstash日志換行處理小解

logstash主用于日志實時數據收集、解析&#xff0c;并將數據轉發的工具&#xff0c;內置的功能也相當強大。但&#xff0c;同時意味著&#xff0c;他可能接收到各種情況的數據。 此處&#xff0c;我們主要講解我實際使用中&#xff0c;碰到的一個小問題&#xff0c;換行(\n)。…