模板與泛型編程

函數模板

顯示實例化

區別定義與聲明

T是模板形參 int是模板實參?

inpunt是函數形參 3是函數實參

顯示實例化

模板必須實例化可見 翻譯單元一處定義原則

與內聯函數異同

引入原因:函數模板是為了編譯器兩個階段的處理 內聯函數是為了能在編譯期展開

模板實參的類型推導

推導原則

推導規則示例

1.

  • 函數形參是左值引用/指針:
    • 忽略表達式類型中的引用
    • 將表達式類型與函數形參模式匹配以確定模板實參

2.萬能引用:函數模板的 T&&是萬能引用?

  • 如果實參表達式是右值,那么模板形參被推導為去掉引用的基本類型
  • 如果實參表達式是左值,那么模板形參被推導為左值引用,觸發引用折疊

引用折疊: 當有兩個引用相互綁定時,它們會被折疊成一個引用。在模板實例化期間,引用折疊規則被應用于模板參數。

3、

  • 函數形參不包含引用
    • 忽略表達式類型中的引用
    • 忽略頂層const
    • 數組、函數轉換成相應的指針類型

無法推導的情況

  • 模板實參并非總是能夠推導得到
    • 如果模板形參與函數形參無關,則無法推導
    • 即使相關,也不一定能進行推導,推導成功也可能存在因歧義而無法使用

即使相關,也不一定能進行推導,推導成功也可能存在因歧義而無法使用

  • 在無法推導時,編譯器會選擇使用缺省模板實參
    • 可以為任意位置的模板形參指定缺省模板實參——注意與函數缺省實參的區別

但是缺省只能處理無法推導的情況 不能處理能推導但是有歧義的情況

模板缺省實參和函數缺省實參區別

函數缺省實參要從右向左設置。 模板可以不是

自動推導遇到的幾種情況

1.SPFINAE

函數模板中的替換失敗(Substitution Failure Is Not An Error,簡稱 SFINAE)是一種編譯器處理模板實例化失敗的機制。當嘗試實例化一個模板時,如果由于某些原因導致實例化失敗,編譯器并不會報錯,而是會嘗試使用備選的模板或者進行其他處理。

報錯:沒有匹配的函數 、忽視函數

重載函數 匹配失敗就會找其他模板實例化 忽略掉前一個

2.模板與非模板同時匹配,匹配等級相同,此時選擇非模板的版本

下面的代碼調用了非模板的fun函數

注意 是匹配等級相同的情況才會選擇非模板 如果不同?則會選擇更加完美的匹配

下面的代碼會調用模板fun

3.多個模板同時匹配,此時采用偏序關系確定選擇最特殊的版本

float更加特殊 所以匹配第二個fun

如果同樣特殊就會報錯

標準類型轉換模板

尾置返回類型與類型轉換

  • 顯式實例化定義:template void fun(int)?/?template void fun(int)

  • 顯式實例化聲明:extern template void fun(int)?/?extern template void fun(int)

  • 注意一處定義原則
  • 來源:stackoverflower

  • 注意實例化過程中的模板形參推導

模板特化

函數模板的(完全)特化:

template<> void f(int)?/?template<> void f(int)

  • 并不引入新的(同名)名稱,只是為某個模板針對特定模板實參提供優化算法

避免使用模板的特化

  • 不參與重載解析,會產生反直覺的效果
  • 通常可以用重載代替
  • 一些不便于重載的情況:無法建立模板形參與函數形參的關聯

1.if constexpr解決

?

2.假函數解決

函數模板不能偏特化

C++20auto定義模板參數

類模板

成員函數只有在調用時才會被實例化

證明:程序無法編譯 但是去掉21行就能編譯

  • 類內類模板名稱的簡寫

類模板成員函數類外定義

成員函數模板

類的成員函數模板

類模板的成員函數模板

類內定義

類外定義

友元函數模板

fun是個友元函數模板

類模板的靜態成員

成員對象只有類實例化的時候才會被實例化

static函數只有使用的時候才會實例化

C++11模板參數為友元

類模板的實例化

類模板的顯示實例化

類模板特化

完全特化

偏特化

C++17類模板的實參推導

B x(3)自動推導成B<int>

pair的自動推導

C++17之前的解決方法 函數模板推導

C++20新概念

  • 模板的問題:沒有對模板參數引入相應的限制
    • 參數是否可以正常工作,通常需要閱讀代碼進行理解
    • 編譯報錯友好性較差(vector<int&>)

  • (C++20)Concepts:編譯期謂詞,基于給定的輸入,返回truefalse
    • constraintsrequire從句)一起使用時限制模板參數
    • 通常置于表示模板形參的尖括號后面進行限制

此處限制T是int和float

優點:報錯一目了然

Concept的定義與使用

  • 1.包含一個模板參數的Concept
    • 使用requires從句
    • 直接替換typename

  • 2.包含多個模板參數Concept
    • 用做類型constraint時,少傳遞一個參數,推導出的類型將作為首個參數

requires 表達式 (C++20 起) - cppreference.com? ?參考資料

  • 簡單表達式:表明可以接收的操作

  • 類型表達式:表明是一個有效的類型

  • requires從句所引入的限定具有偏序特性,系統會選擇限制最嚴格的版本

如下 C1更嚴格 編譯器選擇匹配C1

  • 特化小技巧:在聲明中引入“A||B”進行限制,之后分別針對AB引入特化

重載與模板

數值模板參數與模板模板參數

模板可以接受編譯器常量為模板參數

C++17auto value

·

C++20支持浮點數作為模板參數(clang 12不支持)

接受模板作為模板參數

C++17模板的模板考慮缺省實參

clang12支持有限

別名模板

  • 為目標本身引入別名

  • 為類模板的成員引入別名

  • 別名模板不支持特化,但可以基于類模板的特化引入別名,以實現類似特化的功能
    • 注意與實參推導的關系

變長模板

變長模板(Variadic Template)

  • 變長模板參數與參數包

形參包(parameter pack)是C++中用于處理可變數量參數的一種特性。形參包可以接受任意數量的模板參數,并在模板中進行處理。

形參包的基本語法是使用...來表示,可以用在函數模板、類模板以及別的模板上下文中。形參包的展開可以通過遞歸、折疊表達式(C++17引入)等方式進行。

接數值

接類型

帶可選名字的函數形參包

完美轉發

右值引用失效

使用萬能引用 T&&情況

還是失效 原因:右值引用是個左值

解決方法:轉發 forward

  • (C++11)完美轉發:std::forward函數
    • 通常與萬能引用結合使用
    • 同時處理傳入參數是左值或右值的情形

包展開與折疊表達式

消除歧義

internal*p被編譯器解讀成乘法

  • 使用typenametemplate消除歧義
    • 使用typename表示一個依賴名稱是類型而非靜態數據成員

使用template表示一個依賴名稱是模板

T::internal<A 會被編譯器視為小于號比較大小

使用template表示一個依賴名稱是模板

template與成員函數模板調用

internal被解讀為依賴obj <被解讀成小于號

解決方法

C++14變量模板

  • (C++14)變量模板
    • template<typename T> T pi = (T)3.1415926;
    • 其他形式的變量模板

C++14 引入了變量模板(Variable Templates)的概念,它允許你定義參數化的變量,類似于函數模板允許你定義參數化的函數。變量模板提供了一種通用的方式來定義與類型相關的常量或變量,使得代碼更具有通用性和靈活性。

lambda模板表達式

// 使用 C++20 中的 lambda 模板auto genericLambda = []<typename T>(T x, T y) {return x + y;};

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

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

相關文章

Android Kotlin語言下的文件存儲

目錄 將數據存儲到文件中 創建文件和保存數據 讀取文件 SharedPreferences存儲 存儲數據到SharedPreferences中 Context類中的getSharedPreferences()方法 Activity類中的getPreferences()方法 從SharedPreferences中讀取數據 SQLite數據庫存儲 創建數據庫 調用數據…

Java導出word

原文地址 傳入的值不能為null,否則會報錯&#xff0c;IXDocReport 有自己的判null規則&#xff0c;比較麻煩&#xff0c;建議代碼直接把null替換成"" public void exportWord1(WeeklyMeetDataDto dto, HttpServletResponse response) {ServletOutputStream downLoad…

Ignis - Interactive Fire System

Ignis - 點火、蔓延、熄滅、定制! 全方位火焰系統。 這個插件在21年的項目中使用過很好用值使用概述 想玩火嗎?如果想的話,那么Ignis就是你的最佳工具。有了Ignis,你可以把任何物體、植被或帶皮帶骨的網狀物轉換為可燃物體,它就會自動著火。然后,火焰可以蔓延,點燃其他物…

Java 一對多

前言 Internet 協議集支持一個無連接的傳輸協議&#xff0c;該協議稱為用戶數據報協議&#xff08;UDP&#xff0c;User Datagram Protocol&#xff09;。UDP 為應用程序提供了一種無需建立連接就可以發送封裝的 IP 數據包的方法。 此代碼就是基于UDP協議編寫。 通常把一對多的…

【docker 】centOS 安裝docker

官網 docker官網 github源碼 卸載舊版本 sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine 安裝軟件包 yum install -y yum-utils \device-mapper-persistent-data…

【優選算法系列】【專題二滑動窗口】第四節.30. 串聯所有單詞的子串和76. 最小覆蓋子串

文章目錄 前言一、串聯所有單詞的子串 1.1 題目描述 1.2 題目解析 1.2.1 算法原理 1.2.2 代碼編寫 1.2.3 題目總結二、最小覆蓋子串 2.1 題目描述 2.2 題目解析 2.2.1 算法原理 2.2.2 代碼編寫 …

【Docker】進階之路:(四)操作容器

【Docker】進階之路&#xff1a;&#xff08;四&#xff09;Docker容器 容器的生命周期創建容器docker createdocker run 管理容器查看運行的容器&#xff1a;查看所有容器&#xff1a; 啟動與終止啟動容器終止容器 進入容器docker attachdocker exec 導出和導入導出導入 容器的…

淺談5G基站節能及數字化管理解決方案的設計與應用-安科瑞 蔣靜

截至2023年10月&#xff0c;我國5G基站總數達321.5萬個&#xff0c;占全國通信基站總數的28.1%。然而&#xff0c;隨著5G基站數量的快速增長&#xff0c;基站的能耗問題也逐漸日益凸顯&#xff0c;基站的用電給運營商帶來了巨大的電費開支壓力&#xff0c;降低5G基站的能耗成為…

actitivi自定義屬性(二)

聲明&#xff1a;此處activiti版本為6.0 此文章介紹后端自定義屬性解析&#xff0c;前端添加自定義屬性方法連接&#xff1a;activiti自定義屬性&#xff08;一&#xff09;_ruoyi activiti自定義標題-CSDN博客 1、涉及到的類如下&#xff1a; 簡介&#xff1a;DefaultXmlPar…

在 JavaScript 中導入和導出 Excel XLSX 文件:SpreadJS

在 JavaScript 中導入和導出 Excel XLSX 文件 2023 年 12 月 5 日 使用 MESCIUS 的 SpreadJS 將完整的 JavaScript 電子表格添加到您的企業應用程序中。 SpreadJS 是一個完整的企業 JavaScript 電子表格解決方案&#xff0c;用于創建財務報告和儀表板、預算和預測模型、科學、工…

【華為OD】給定一個只包括 ‘(‘,‘)‘,‘{‘,‘}‘,‘[‘,‘]‘ 的字符串

給定一個只包括 (,),{,},[,] 的字符串 s , 判斷字符串是否有效。 有效字符串需滿足: 左括號必須用相同類型的右括號閉合。 左括號必須以正確的順序閉合。 示例 1 : 輸入:s="()" 輸出 : true 示例 2 :

圖的搜索(一):廣度優先搜索算法和深度優先搜索算法

圖的搜索&#xff08;一&#xff09;&#xff1a;廣度優先搜索算法和深度優先搜索算法 本章主要記錄了圖的搜索算法&#xff0c;和可以解決圖的基本問題——最短路徑問題的算法。本章主要對圖搜索的相關算法進行了介紹&#xff1a;廣度優先搜索算法、深度優先搜索算法。 下一…

公網域名如何解析到內網IP服務器——快解析域名映射外網訪問

在本地搭建主機應用后&#xff0c;由于沒有公網IP或沒有公網路由權限&#xff0c;在需要發布互聯網時&#xff0c;就需要用到外網訪問內網的一些方案。由于內網IP在外網不能直接訪問&#xff0c;通常就用通過外網域名來訪問內網的方法。那么&#xff0c;公網域名如何解析到內網…

Tmux中使用Docker報錯 - 解決方案

問題 進入Tmux會話后&#xff0c;在其中使用Docker可能會出現如下報錯&#xff1a; Got permission denied while trying to connect to the Docker ……解決方案 退出tmux會話: tmux detach在tmux會話外部殺掉tmux進程&#xff1a; pkill -f tmux重新進入tmux&#xff1a…

權威認證!景聯文科技入選杭州市2023年第二批省級“專精特新”中小企業認定名單

為深入貫徹黨中央國務院和省委省政府培育專精特新的決策部署&#xff0c;10月7日&#xff0c;杭州市經濟和信息化委員會公示了2023年杭州“專精特新”企業名單&#xff08;第二批&#xff09;。 根據工業和信息化部《優質中小企業梯度培育管理暫行辦法》&#xff08;工信部企業…

【Vue3+Ts項目】硅谷甄選 — 路由配置+登錄模塊+layout組件+路由鑒權

一、路由配置 項目一共需要4個一級路由&#xff1a;登錄&#xff08;login&#xff09;、主頁&#xff08;home&#xff09;、404、任意路由&#xff08;重定向到404&#xff09;。 1.1 安裝路由插件 pnpm install vue-router 1.2 創建路由組件 在src目錄下新建views文件…

Graphpad Prism10.1.0 安裝教程 (含Win/Mac版)

GraphPad Prism GraphPad Prism是一款非常專業強大的科研醫學生物數據處理繪圖軟件&#xff0c;它可以將科學圖形、綜合曲線擬合&#xff08;非線性回歸&#xff09;、可理解的統計數據、數據組織結合在一起&#xff0c;除了最基本的數據統計分析外&#xff0c;還能自動生成統…

Python:核心知識點整理大全8-筆記

目錄 ?編輯 4.5 元組 4.5.1 定義元組 dimensions.py 4.5.2 遍歷元組中的所有值 4.5.3 修改元組變量 4.6 設置代碼格式 4.6.1 格式設置指南 4.6.2 縮進 4.6.3 行長 4.6.4 空行 4.6.5 其他格式設置指南 4.7 小結 第5章 if語句 5.1 一個簡單示例 cars.py 5.2 條…

現代皮質沙發模型材質編輯

在線工具推薦&#xff1a; 3D數字孿生場景編輯器 - GLTF/GLB材質紋理編輯器 - 3D模型在線轉換 - Three.js AI自動紋理開發包 - YOLO 虛幻合成數據生成器 - 三維模型預覽圖生成器 - 3D模型語義搜索引擎 當談到游戲角色的3D模型風格時&#xff0c;有幾種不同的風格&#xf…

線性容器(QByteArray、QString、QList模板類)、堆棧窗體

QT 線性容器 點擊查看&#xff1a;字符和字節的區別&#xff0c;ASCII、Unicode 和 UTF-8 編碼的區別。&#xff08;&#x1f448; 安全鏈接&#xff0c;放心跳轉&#xff09; QByteArray 思考&#xff1a;char buf[6] “hello”; 如果 C 語言中要利用 buf 內容重新生成 “…