1. 程式人生 > >002-EMC 深入解讀-理解模板型別推導(二)

002-EMC 深入解讀-理解模板型別推導(二)

接下來,從三種不同的情況來討論函式模板推導規則:

  • ParamType 是引用或指標,但不是通用引用
  • ParamType 是通用引用
  • ParamType 既非指標也非引用

1. ParamType 是引用或指標,但不是通用引用

template<typename T>
void f(ParamType param) // 例如:ParamType = T&,ParamType = const T&, ParamType = T*

f(expr);
  • step 1. 若 expr 具有引用型別,先將引用部分忽略。
  • step 2. 對 expr 的型別與 ParamType 匹配,決定 T 的型別。我們簡單的用 type of expr = ParamType,對 T 進行計算。

step 1 非常容易理解,step 2 舉個例子,你也就會了。

例 1:

template<typename T>
void f(T& param) 

int x = 27;
const int cx = x;
const int& rx = x;

// Step 1. expr = x, expr 的型別是 int
// Step 2. int = T,=> T = int
f(x); // T = int, ParamType = T& = int&

// Step 1. expr = cx, expr 的型別是 const int
// Step 2. const int = T,=> T = const int
f(cx); // T = int, ParamType = T& = const int& // Step 1. expr = rx, expr 的型別是 const int&,忽略引用部分,變成 const int // Step 2. const int = T,=> T = const int f(rx); // T = const int, ParamType = T& = const int&

上面的例子需要注意的地方在於,type of expr = ParamType,注意把 ParamType 中的 & 先去掉。

例 2:

template
<typename T> void f(const T& param) int x = 27; const int cx = x; const int& rx = x; // Step 1. expr = x, expr 的型別是 int // Step 2. int = const T,=> T = int (因為 = 左側的 int 沒有 const, // 相消的角度來看,T 沒法被推導,但在這裡,我們採取儘可能讓等式兩邊相等的策略執行匹配, // 因此只有 T = int 最合適) f(x); // T = int, ParamType = const T& = const int& // Step 1. expr = cx, expr 的型別是 const int // Step 2. const int 與 const T 執行模式匹配,=> T = int f(cx); // T = int, ParamType = const T& = const int& // Step 1. expr = rx, expr 的型別是 const int&,忽略引用部分,變成 const int // Step 2. const int = const T,=> T = int f(rx); // T = int, ParamType = const T& = const int&
  • 例3
template<typename T>
void f(T* param) 

int x = 27;
const int* px = &x;

// Step 1. expr = &x, expr 的型別是 int*
// Step 2. int* = T*,=> T = int
f(&x); // T = int, ParamType = T* = int*

// Step 1. expr = px, expr 的型別是 const int*
// Step 2. const int* = T*,=> T = const int
f(px); // T = int, ParamType = T* = const int*
  • 例4
template<typename T>
void f(const T* param) 

int x = 27;
const int* px = &x;

// Step 1. expr = &x, expr 的型別是 int*
// Step 2. int* = const T*,=> T = int (同例 2,只有 T 被推導為 int 的時候,等式兩邊最接近)
f(&x); // T = int, ParamType = const T* = const int*

// Step 1. expr = px, expr 的型別是 const int*
// Step 2. const int* = const T*,=> T = int
f(px); // T = int, ParamType = const T* = const int*

2. 實驗

在這個系列的文章中,我準備了大量的程式碼來驗證我們的想法。您可以拉取所有程式碼進行閱讀,歡迎隨時留言提問。

2.1 void f(T& param)

路徑:emc/item01/demo01.cpp

這裡寫圖片描述

2.2 void f(const T& param)

路徑:emc/item01/demo02.cpp

這裡寫圖片描述

2.3 void f(T* param)

路徑:emc/item01/demo03.cpp

這裡寫圖片描述

3. 總結

  • 掌握 ParamType 為引用或指標但不是通用引用的推導規則

下一篇,我們介紹通用引用的推導規則。

相關推薦

002-EMC 深入解讀-理解模板型別推導

接下來,從三種不同的情況來討論函式模板推導規則: ParamType 是引用或指標,但不是通用引用 ParamType 是通用引用 ParamType 既非指標也非引用 1. ParamType 是引用或指標,但不是通用引用 template&

003-EMC 深入解讀-理解模板型別推導

上一篇文章我們介紹了 ParamType 是引用或指標的情況,這一節繼續第二條規則,也是最複雜的規則。 ParamType 是引用或指標,但不是通用引用 ParamType 是通用引用 ParamTy

C++11 條款1:理解模板型別推導

前言 c++98有單獨一套型別推導規則:適用於函式模板。c++11修改了這套規則並且增加了兩個,一個是auto,一個是decltype。c++14擴充套件了auto和decltype使用的場景。隨著型別推導在應用程式中的使用逐步增加,你可以從那些明顯或冗餘的型別拼寫中

深入理解線性迴歸演算法:正則項的詳細分析

前言 當模型的複雜度達到一定程度時,則模型處於過擬合狀態,類似這種意思相信大家看到個很多次了,本文首先討論了怎麼去理解複雜度這一概念,然後回顧貝葉斯思想(原諒我有點囉嗦),並從貝葉斯的角度去理解正則項的含義以及正則項降低模型複雜度的方法,最後總結全文。     &nb

深入理解Java虛擬機器——類載入器深入解析

類載入過程 •類載入:類載入器將class檔案載入到虛擬機器的記憶體  •載入:在硬碟上查詢並通過IO讀入位元組碼檔案 •連線:執行校驗、準備、解析(可選)步驟 •校驗:校驗位元組碼檔案的正確性

深入理解java虛擬機器

前言 上篇已經介紹到記憶體結構劃分《深入理解java虛擬機器一》,本篇將介紹jvm記憶體分配。 正文 這裡主要介紹物件記憶體的分配,而物件是在堆中分配記憶體的,堆可以分為新年代和老年代,其中新年代可以劃分為Eden區和Survivor區,而Survivor又可以進一步劃

深入理解Java記憶體模型——重排序

資料依賴性 如果兩個操作訪問同一個變數,且這兩個操作中有一個為寫操作,此時這兩個操作之間就存在資料依賴性。資料依賴分下列三種類型: 名稱 程式碼示例 說明 寫後讀 a = 1;b = a; 寫一個變數之後,再讀這個位置。 寫後寫 a = 1;a = 2; 寫一個變數之後,再寫這

iOS開發——響應鏈(Responder Chain)的深入理解和程式碼示例

        響應鏈機制是開發中很重要的概念,在一些事件的處理中需要對響應鏈的傳遞有深入的瞭解,我們才能對事件的傳遞有更好的控制。今天我們繼續來研究下響應鏈,並實現一個很簡單的功能。示例程式碼已經上傳至 https://github.com/chenyufeng1991/H

深入理解maven與應用:靈活的構建

 一個優秀的構建系統必須足夠靈活,應該能夠讓專案在不同的環境下都能成功構建。maven為了支援構建的靈活性,內建了三大特性,即:屬性、profile和資源過濾。 1、maven屬性  maven屬性分6類:     1、內建屬性:如${basedir}表示專案根目錄,$

深入理解多執行緒—— Java的物件模型

上一篇文章中簡單介紹過synchronized關鍵字的方式,其中,同步程式碼塊使用monitorenter和monitorexit兩個指令實現,同步方法使用ACC_SYNCHRONIZED標記符實現。後面幾篇文章會從JVM原始碼的角度更加深入,層層剝開synchronized

JavaScript: ----深入理解JS執行上下文

占位符 例子 -s 名稱 活動對象 {} undefined 行處理 對象 上篇文章我們了解到:js解析器會在(全局代碼/函數/eval代碼)執行前創建一個與之對應的執行上下文, 而對於每個執行上下文,都會有三個重要屬性: 變量對象(Variable object

機器學習 | 深入SVM原理及模型推導

本文始發於個人公眾號:**TechFlow**,原創不易,求個關注 今天是**機器學習專題**的第32篇文章,我們來聊聊SVM。 SVM模型大家可能非常熟悉,可能都知道它是面試的常客,經常被問到。它最早誕生於上世紀六十年代。那時候雖然沒有機器學習的概念,也沒有這麼強的計算能力,但是相關的模型和理論已經

C++ 模板詳解

創建 規則 error ++ 例如 public err iostream () 四、類模板的默認模板類型形參   1、可以為類模板的類型形參提供默認值,但不能為函數模板的類型形參提供默認值。函數模板和類模板都可以為模板的非類型形參提供默認值。   2、類模板的類型形

WPF Button按鈕模板樣式修改

本章講述:Button模板樣式修改,不顯示邊框,只顯示圖示,點選按鈕圖示動態旋轉; 主要採用採用圖片做背景和資料觸發器,觸發故事板(Storyboard)事件,實現按鈕中圖片按角度旋轉; <Button Width="30" Height="30"> <Butt

深入Java網路程式設計與NIO

Java NIO 與 Netty NIO NIO的特性/NIO與IO區別: 1)IO是面向流的,NIO是面向緩衝區的; 2)IO流是阻塞的,NIO流是不阻塞的; 3)NIO有選擇器,而IO沒有。 讀資料和寫資料方式: 從通道進行資料讀取 :建立一個緩衝區,然後請求通道讀取資料。

深入Java虛擬機器閱讀感-Java垃圾回收器與記憶體分配策略

垃圾回收器主要演算法:       1、引用計數法。給物件新增一個計數器,當物件被使用時則加1,當引用失效時則減1,當計數為0時則認為該物件可以被回收。由於該算演算法無法解決物件相互引用而計數不會減為0,導致該物件無法回收,所以該演算法不是Java虛擬垃圾回收器

程式設計與演算法第九周 標準模板庫STL2

STL演算法(一) STL演算法分類 不變序列演算法 變值演算法 刪除演算法 變序演算法 排序演算法 有序區間演算法 數值演算法 大多數過載的演算法都是有兩個版本的 用“==”判斷元素是否相等,或

看動畫輕鬆理解時間複雜度

    上篇文章講述了與複雜度有關的大 O 表示法和常見的時間複雜度量級,這篇文章來講講另外幾種複雜度: 遞迴演算法的時間複雜度(recursive algorithm time complexity),最好情況時間複雜度(best case time complexity)、最壞情況

【轉】深入淺出理解決策樹演算法-ID3演算法與C4.5演算法

從深入淺出理解決策樹演算法(一)-核心思想 - 知乎專欄文章中,我們已經知道了決策樹最基本也是最核心的思想。那就是其實決策樹就是可以看做一個if-then規則的集合。我們從決策樹的根結點到每一個都葉結點構建一條規則。 並且我們將要預測的例項都可以被一條路徑或者一條規則所覆蓋。 如下例:假設我

Scala入門到精通——第二十節 型別引數

本節主要內容 Ordering與Ordered特質 上下文界定(Context Bound) 多重界定 型別約束 1. Ordering與Ordered特質 在介紹上下文界定之前,我們對scala中的Ordering與Ordered之間的關聯與區別