国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【c++ primer 筆記】第 16章 模板與泛型編程

這篇具有很好參考價(jià)值的文章主要介紹了【c++ primer 筆記】第 16章 模板與泛型編程。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言

??作者簡(jiǎn)介:?? 博主在讀機(jī)器人研究生,目前研一。對(duì)計(jì)算機(jī)后端感興趣,喜歡 c + + , g o , p y t h o n , 目前熟悉 c + + , g o 語言,數(shù)據(jù)庫,網(wǎng)絡(luò)編程,了解分布式等相關(guān)內(nèi)容 \textcolor{orange}{博主在讀機(jī)器人研究生,目前研一。對(duì)計(jì)算機(jī)后端感興趣,喜歡c++,go,python,目前熟悉c++,go語言,數(shù)據(jù)庫,網(wǎng)絡(luò)編程,了解分布式等相關(guān)內(nèi)容} 博主在讀機(jī)器人研究生,目前研一。對(duì)計(jì)算機(jī)后端感興趣,喜歡c++,go,python,目前熟悉c++,go語言,數(shù)據(jù)庫,網(wǎng)絡(luò)編程,了解分布式等相關(guān)內(nèi)容
?? 個(gè)人主頁: \textcolor{gray}{個(gè)人主頁:} 個(gè)人主頁: 小呆鳥_coding
?? 支持 : \textcolor{gray}{支持:} 支持: 如果覺得博主的文章還不錯(cuò)或者您用得到的話,可以免費(fèi)的關(guān)注一下博主,如果三連收藏支持就更好啦 \textcolor{green}{如果覺得博主的文章還不錯(cuò)或者您用得到的話,可以免費(fèi)的關(guān)注一下博主,如果三連收藏支持就更好啦} 如果覺得博主的文章還不錯(cuò)或者您用得到的話,可以免費(fèi)的關(guān)注一下博主,如果三連收藏支持就更好啦?? 就是給予我最大的支持! \textcolor{green}{就是給予我最大的支持!} 就是給予我最大的支持!??
??本文摘要??

本專欄主要是對(duì)c++ primer這本圣經(jīng)的總結(jié),以及每章的相關(guān)筆記。目前正在復(fù)習(xí)這本書。同時(shí)希望能夠幫助大家一起,學(xué)完這本書。 本文主要講解第16章 模板與泛型編程

c++ primer 第五版 系列文章:可面試可復(fù)習(xí)

第2章 變量和基本類型
第3章 字符串、向量和數(shù)組
第4章 表達(dá)式
第5章 語句
第6章 函數(shù)
第8章 IO庫
第9章 順序容器
第10章 泛型算法
第11章 關(guān)聯(lián)容器
第12章 動(dòng)態(tài)內(nèi)存
第13章 拷貝控制
第 14章 重載運(yùn)算符
第15章 面向?qū)ο蟪绦蛟O(shè)計(jì)
第 16章 模板與泛型編程

??模板與泛型編程

  • 面向?qū)ο缶幊?/code>和泛型編程都能處理在編寫程序時(shí)不知道類型的情況
    1. OOP 能處理類型在程序運(yùn)行之前都未知的情況。
    2. 泛型編程在編譯時(shí)就能知道類型了。容器、迭代器、泛型算法都是泛型編程的例子。
      模板是泛型編程的基礎(chǔ),一個(gè)模板就是一個(gè)創(chuàng)建類或函數(shù)的藍(lán)圖。

??16.1 定義模板

??16.1.1 函數(shù)模板

  • 模板定義以關(guān)鍵字 template 開始,后跟一個(gè)用 <> 包圍,用逗號(hào)分隔的模板參數(shù)列表。

  • 在模板定義中,模板參數(shù)列表不能為空

  • 模板參數(shù)列表類似函數(shù)列表,需要在類或函數(shù)定義中用到的類型和值。使用模板時(shí),需要指定模板實(shí)參,將其綁定到模板參數(shù)上。

'普通函數(shù)'

int compare(const string &v1, const string &v2)
{
	if (v1 < v2) return -1;
	if (v2 < v1) return 1;
	return 0;
}
'模板'
template <typename T>
bool compare(const T &v1, const T &v2)
{
   if (v1 < v2) return -1;
   if (v2 < v1) return 1;
   return 0;
}

實(shí)例化函數(shù)模板

  • 調(diào)用函數(shù)模板時(shí),編譯器用函數(shù)實(shí)參來推斷模板實(shí)參,然后實(shí)例化出一個(gè)特定版本的函數(shù)。
//實(shí)例化出int compare(const int &, const int &)
cout << compare(1, 0) << endl;  //T為int

//實(shí)例化int compare(const vector<int> &, const vector<int> &)
vector<int> vec1{1, 2, 3}, vec{4, 5, 6};

模板類型參數(shù)

  • 模板類型參數(shù)當(dāng)做內(nèi)置類型或類類型一樣使用
  • 類型參數(shù)可以用來指定返回類型或函數(shù)的參數(shù)類型
  • 模板參數(shù)前必須使用關(guān)鍵字 class 或 typename,兩個(gè)含義相同。
'正確'
template <typename T, class U> calc(const T&, const U&);
'錯(cuò)誤'
template <typename T,  U> calc(const T&, const U&);
//T參數(shù)返回類型, T* p參數(shù)類型
template <typename T> T foo(T* p) 
{
	 T tmp = *p
	 return *p; 
}

'實(shí)例'
int a = 0;
int foo(int *p)
{
	int tmp = *p;
	return tmp;
} 

cout << foo(& a) << endl;

非類型模板參數(shù)

  • 可以在模板中定義非類型參數(shù)。一個(gè)非類型參數(shù)表示一個(gè)值而非一個(gè)類型。
  • 通過一個(gè)特定的類型名(如int, double等)而非關(guān)鍵字class或typename來指定非類型參數(shù)
  • 當(dāng)一個(gè)模板實(shí)例化時(shí),非類型參數(shù)被用戶提供的值所代替,這些值必須是常量表達(dá)式,以允許編譯器在編譯時(shí)實(shí)例化模板。
  • 非類型參數(shù)可以是一個(gè)整型或指針或引用。綁定到指針或引用非類型參數(shù)的實(shí)參必須具有靜態(tài)的生存期。
  • 非類型模板參數(shù)的模板實(shí)參必須是常量表達(dá)式(例如指定數(shù)組大?。?/code>
template <unsigned N, unsigned M>
int compare(const char (&p1)[N], const char (&p2)[M]) 
{ 
	return strcmp(p1, p2); 
}//定義了一個(gè)函數(shù)模板。
compare("hi", "mom");//實(shí)例化

'實(shí)例化的版本'
int compare(const char (&p1)[3], const char (&p2)[M]);
//編譯器會(huì)在一個(gè)字符串字面值常量的末尾插入一個(gè)空字符作為終結(jié)符
  • 注意
    • 一般對(duì)于非類型模板參數(shù),限制const此時(shí)可以傳遞const和非const

inline 和 constexpr 的函數(shù)模板

  • 函數(shù)模板可以聲明為 inline 或 constexpr 的。
  • 與普通函數(shù)不同,inline和constexpr說明符放在模板參數(shù)列表之后,返回類型之前
template<typename T> inline T main(const T&, const T&);

編寫類型無關(guān)的代碼

  • 編寫泛型代碼有兩個(gè)重要原則:
    1. 模板中的函數(shù)參數(shù)應(yīng)該是 const 的引用。引用保證了函數(shù)可以用于不能拷貝的類型,如unique_ptr, IO 類型。
    2. 函數(shù)體中的條件判斷僅使用 < 比較運(yùn)算。
//缺點(diǎn):對(duì)類型要求比較高,如果調(diào)用它比較倆個(gè)指針,且指針未指向相同的數(shù)組,則會(huì)出錯(cuò)
if (v1 < v2) return -1;
if (v1 > v1) return 1;
return ;

//傳遞指針也正確
template <typename T>
int compare(const T &v1, const T &v2)
{
	if (less<T>()(v1, v2)) return -1;
	if (less<T>()(v2, v1)) return 1;
	return 0;
}
  • 注意:
  • 模板程序應(yīng)該盡量減少對(duì)實(shí)參類型要求

模板編譯

  • 編譯器遇到模板定義時(shí)不生成代碼,當(dāng)實(shí)例化出模板的一個(gè)特定版本時(shí)才生成代碼。這會(huì)影響錯(cuò)誤何時(shí)被檢測(cè)到。
  • 定義類時(shí),普通的成員函數(shù)一般放在源文件中。但是模板不同,模板的頭文件通常既包括聲明也包括定義。因?yàn)榫幾g器需要知道函數(shù)模板或類模板成員函數(shù)的完整定義才能進(jìn)行實(shí)例化。

大多數(shù)編譯錯(cuò)誤在實(shí)例化期間報(bào)告

  • 第一階段:編譯模板本身時(shí)。只能檢測(cè)到語法錯(cuò)誤。
  • 第二階段:編譯器遇到模板使用時(shí)。只能檢測(cè)模板實(shí)參是否與形參相匹配。
  • 第三階段:模板實(shí)例化時(shí)。這時(shí)才能發(fā)現(xiàn)類型相關(guān)的錯(cuò)誤。

??16.1.2 類模板

  • 類模板與函數(shù)模板不同,編譯器不能為類模板推斷模板參數(shù)類型。通過在模板名后的尖括號(hào)中提供額外信息,來代替模板參數(shù)的模板實(shí)參列表

定義類模板

template <typename T> class Blob {}

實(shí)例化類模板

  • 當(dāng)使用一個(gè)類模板時(shí),必須提供額外的信息,也就是顯示模板實(shí)參列表,他們被綁定到模板參數(shù)
Blob<int> ia;                    //使用類模板
template <> class Blob<int> {};  // 當(dāng)向上一行那樣使用類模板時(shí),編譯器實(shí)例化出的類就是這樣的。
  • 編譯器從Blob模板實(shí)例化出一個(gè)類時(shí),他會(huì)重寫B(tài)lob類,將模板參數(shù)T的每個(gè)實(shí)例,替換為給定的模板實(shí)參,上面就全部替換成了int類型

注意

  • 一個(gè)類模板的每一個(gè)實(shí)例都能形成一個(gè)獨(dú)立的類。例如Blob<string>與Blob<double>類型沒有關(guān)聯(lián),也不會(huì)有特殊的訪問權(quán)限,這完全就是倆個(gè)獨(dú)立的Blob類
//定義的實(shí)例化出倆個(gè)不同的Blob類型
Blob<string> names;
Blob<double> prices;

類模板的成員函數(shù)

  • 可以在類模板內(nèi)部,也可以在外部定義成員函數(shù)。定義在類模板內(nèi)部的函數(shù)隱式聲明為內(nèi)聯(lián)函數(shù)。
  • 定義在類模板之外的成員函數(shù)必須以關(guān)鍵字 template 開始,后接類模板參數(shù)列表。
'格式'
template <typename T>
ret_type Blob<T>::member_name(parm-list)

template <typename T> void Blob<T>::check(){}
templte <typename T> T& Blob<T>::operator[]{}
//Blob<T>::在外部定義成員函數(shù)是,必須說明成員屬于哪一個(gè)類
//模板實(shí)參與模板形參必須相同

類模板成員函數(shù)的實(shí)例化

  • 默認(rèn)情況下,一個(gè)類模板的成員函數(shù)只有當(dāng)用到它時(shí)才進(jìn)行實(shí)例化。
  • 如果一個(gè)成員函數(shù)沒有被使用,則它不會(huì)實(shí)例化。

在類代碼內(nèi)簡(jiǎn)化模板類名的使用

  • 使用一個(gè)類模板類型時(shí)必須提供模板實(shí)參,在一個(gè)類模板的作用域內(nèi),可以直接使用模板而不敗指定模板實(shí)參
  • 在類模板外使用類模板名必須提供模板實(shí)參。

template <typename T> class BlobPtr{
	BlobPtr<T>& operator++();
	BlobPtr<T>& operator--();

};
'在類的作用域(內(nèi)部)可以省略'
template <typename T> class BlobPtr{
	BlobPtr& operator++();
	BlobPtr& operator--();

};

在類模板外使用類模板名

  • 當(dāng)在類模板定義其成員時(shí),必須記住,我們并不在類的作用域中,直到遇到類名才表示進(jìn)入類的作用域

【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言

類模板和友元

  • 如果一個(gè)類模板包含一個(gè)非模板友元,則該友元可以訪問該模板的所有實(shí)例。
  • 如果友元也是模板,類可以授權(quán)給所有友元模板實(shí)例,也可以只授權(quán)給特定實(shí)例。

一對(duì)一友好關(guān)系

//每個(gè)Blob實(shí)例將訪問權(quán)限授予用相同類型實(shí)例化的BlobPtr和相等運(yùn)算符
template <typename T> class Blob{

	'友元的T和上面的T類型必須一致'
    friend class BlobPtr<T>;  // 每個(gè) Blob 實(shí)例將訪問權(quán)限授予了同類型實(shí)例化的 BlobPtr。
    friend bool operator==<T> (const Blob<T>&,const Blob<T>&); // 將訪問權(quán)限授予同類型實(shí)例化的 ==。
}

'友元的聲明用Blob的模板形參作為他們自己的模板實(shí)參'
'因此友好關(guān)系被限制在相同類型實(shí)例化的Blob和BlobPtr之間'

Blob<char> ca; // BlobPtr<char>和operator==<char> 都是本對(duì)象的友元
Blob<int> ia; // BlobPtr<int>和operator==<int> 都是本對(duì)象的友元

'注意:'
BlobPtr<char> 的成員可以訪問ca的非public部分,但是ca對(duì)ia或其他Blob的任何實(shí)例沒有特殊訪問權(quán)限

通用和特定的模板友好關(guān)系

【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言

  • 為了讓所有實(shí)例都成為友元,友元聲明中必須使用與類模板不同的模板參數(shù)。
template <typename T> class Blob{
    template <typename X> friend class Pal;  // Pal 的所有實(shí)例都是 Blob 的每個(gè)實(shí)例的友元。
}

令模板自己的類型參數(shù)成為友元

template <typename T> class Blob{
    friend T; // 將訪問權(quán)限授予用來實(shí)例化 Blob 的類型
}

模板類型別名

  • 可以定義一個(gè) typedef 來引用實(shí)例化的類,但不能引用模板
typedef Blob<string> StrBlob;//正確
  • 可以用 using 為類模板定義類型別名
template <typename T> using twins = pair<T, T>; // 為 pair<T, T> 定義了一個(gè)類型別名 twins
twins<string> authors;  // authors 是一個(gè) pair<string,string>。

'可以固定一個(gè)或多個(gè)模板參數(shù),上面只是固定一個(gè)'
template <typename T> using partNo = pair<T, unsigned>;
partNo<string>book; //pair<string, unsigned>
  • 定義模板類型別名時(shí),可以固定其中的部分模板參數(shù)
template <typename T> using twins = pair<T, unsigned>;  // 為 pair<T, unsigned> 定義了一個(gè)類型別名 twins
twins<string> authors;  // authors 是一個(gè) pair<string, unsigned>。

類模板的 static 成員

  • 如果類模板定義了 static 成員,那么模板的每個(gè)實(shí)例都有自己獨(dú)有的 static 成員實(shí)例。
  • static 數(shù)據(jù)成員定義時(shí)也要定義為模板

【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言

template <typename T> int Blob<T>::num = 0;  // 在類模板外定義 static 數(shù)據(jù)成員的方式。
  • 可以通過域訪問符::訪問里面靜態(tài)成員,使用時(shí)才會(huì)被實(shí)例化,也可以通過對(duì)象訪問,
  • 但是不能通過模板訪問,因?yàn)槌蓡T必須有個(gè)具體的類才行。
    【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言

??16.1.3 模板參數(shù)

  • 一個(gè)模板參數(shù)的名字沒有實(shí)際意義,既可以寫T,也可以寫其他的名字

模板參數(shù)與作用域

  • 模板參數(shù)的可用范圍是其聲明之后,至模板聲明或定義結(jié)束之前。
  • 模板參數(shù)會(huì)隱藏外層作用域中的相同名字,但是注意在模板內(nèi)不能重用模板參數(shù)名。
  • 一個(gè)模板參數(shù)名在一個(gè)特定模板參數(shù)列表中只能出現(xiàn)一次
typedef double A;
template <typename A, typename B> void f(A a, B b)
{
	A tmp = a;        //tmp的類型為模板參數(shù)A的類型,而非double
	double B;         //錯(cuò)誤:重聲明模板參數(shù)B
}

模板聲明

  • 模板聲明必須包含模板參數(shù),聲明中的模板參數(shù)的名字不必與定義中相同(與函數(shù)形參類似)。
'3個(gè)calc都指向相同的函數(shù)模板'
template <typename T> T calc (const T &, const T&);  //聲明
template <typename U> U calc (const U&, const T&)    //聲明
template <typename Type> Type calc(const Type& a, const Type& b){....}                    //定義
  • 一個(gè)文件所需要的所有模板的聲明通常都一起放置在文件的開始位置。

使用類的類型成員

  • 默認(rèn)情況下,C++ 假定通過作用域運(yùn)算符訪問的名字不是類型(比如可能是靜態(tài)成員)。
  • 如果希望使用一個(gè)模板類型參數(shù)的類型成員,必須使用關(guān)鍵字 typename 顯式地告訴編譯器該名字是一個(gè)類型,而不能使用class
template <typename T> 
typename T::value_type top (const T&c)
{
	....
}

默認(rèn)模板實(shí)參

  • 可以為函數(shù)模板和類模板的模板參數(shù)提供默認(rèn)模板實(shí)參,就像可以為函數(shù)參數(shù)提供默認(rèn)實(shí)參一樣。
//compare有一個(gè)默認(rèn)模板實(shí)參less<>和一個(gè)默認(rèn)函數(shù)實(shí)參F()
template <typename T, typename F = less<T>>
int compare(const T &v1, const T &v2, F f = F())
{......}

模板默認(rèn)實(shí)參與類模板

  • 如果一個(gè)類模板為其所有模板參數(shù)都提供了默認(rèn)實(shí)參,且希望使用默認(rèn)實(shí)參,必須在模板名后面跟一個(gè)空尖括號(hào)對(duì):

【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言

??16.1.4 成員模板

  • 一個(gè)類(不管是普通類還是類模板)都可以包含本省是模板的成員函數(shù)。
  • 成員模板(member template):本身是模板的函數(shù)成員。
    • 普通(非模板)類的成員模板。
    • 類模板的成員模板。

普通(非模板)類的成員模板

  • 注意:成員模板不能是虛函數(shù)

【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言
類模板的成員模板

  • 可以對(duì)類模板,定義其成員模板,此時(shí)類模板與成員模板都是獨(dú)立的模板
  • 與類模板的普通函數(shù)成員不同的是, 成員模板是函模板。當(dāng)在類模板外定義一個(gè)成員模板時(shí),必須同時(shí)為類模板和成員模板提供模板參數(shù)列表。
template<typename T> class Blob{
	template<typename it> Blob(lt b, lt e);
	....
};

template<typename T>  //類的類型參數(shù)
template<typename ll> //構(gòu)造函數(shù)的類型參數(shù)
	Blob<T>::Blob(lt b, lt e);
		data(std:make_shared<std::vector<T>>(b, e)){}

實(shí)例化與成員模板

  • 實(shí)例化一個(gè)類模板的成員模板,必須同時(shí)提供類和函數(shù)模板的實(shí)參
  • 倆步走:
    • 首先根據(jù)對(duì)象的類型推斷出類模板的參數(shù)的實(shí)參
    • 然后根據(jù)傳遞給成員模板的函數(shù)實(shí)參來推斷它的模板實(shí)參
      【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言
第一步:定義a1時(shí),顯示的指出編譯器應(yīng)該實(shí)例化一個(gè)int版本Blob
第二步:構(gòu)造函數(shù)自己的類型參數(shù)通過begin(a1)end(a1)類型推斷

??16.1.5 控制實(shí)例化

  • 產(chǎn)生控制實(shí)例化原因:

    • 當(dāng)模板被使用時(shí)才會(huì)進(jìn)行實(shí)例化,而每個(gè)模板的源碼都單獨(dú)的放在一個(gè)文件中,當(dāng)進(jìn)行單獨(dú)編譯是,就會(huì)出現(xiàn)重復(fù)(在多個(gè)文件中實(shí)例化相同模板的額外開銷可能非常嚴(yán)重。)
  • 顯示實(shí)例化:

  • extern template declaration; // 實(shí)例化聲明

  • template declaration; // 實(shí)例化定義

extern template class Blob<string>;             //聲明
template int compare(const int &, const int &); //定義

【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言

??16.1.6 效率與靈活性

??16.2 模板實(shí)參推斷

  • 編譯器通常不是對(duì)實(shí)參進(jìn)行類型轉(zhuǎn)換,他不知道到怎么轉(zhuǎn)換,而是生成一個(gè)新的模板實(shí)例

??16.2.1 類型轉(zhuǎn)換與模板類型參數(shù)

  • 通常不會(huì)進(jìn)行類型轉(zhuǎn)換,但是有特例
  • const轉(zhuǎn)換:可以將一個(gè)非const對(duì)象的引用(指針)傳遞給一個(gè)const的引用(或指針)形參
  • 數(shù)組或函數(shù)指針轉(zhuǎn)換:如果函數(shù)形參不是引用類型,則可以將數(shù)組或函數(shù)轉(zhuǎn)換為相應(yīng)的指針。(數(shù)組實(shí)參轉(zhuǎn)換為一個(gè)指向其首元素的指針,函數(shù)實(shí)參轉(zhuǎn)換為指向一個(gè)該函數(shù)類型的指針)

【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言

使用相同 模板參數(shù)類型的函數(shù)形參

  • 一個(gè)模板類型參數(shù)可以用作多個(gè)函數(shù)形參的類型。但是只允許有限的幾種類型轉(zhuǎn)換,因此傳遞給這些形參的實(shí)參必須具有相同的類型
  • 如果推斷出類型不匹配,只能傳遞倆個(gè)類型參數(shù)
long lng;
compare(lng, 1024);   //錯(cuò)誤:不能實(shí)例化compare(lng, 1024);類型不匹配且不能轉(zhuǎn)換

template<typename A, typename B>
int flexibleCompare(const A& v1, const B& v2){....};

long lng;
flexibleCompare(lng, 1024);  //正確但是有一個(gè)條件,這里面?zhèn)z個(gè)類型是兼容的可以進(jìn)行比較。

正常類型轉(zhuǎn)換應(yīng)用于普通函數(shù)實(shí)參

  • 函數(shù)模板可以用普通類型定義的參數(shù),這種函數(shù)可以進(jìn)行進(jìn)行形參的轉(zhuǎn)換(對(duì)于模板類型,只允許幾種情況進(jìn)行自動(dòng)轉(zhuǎn)換,intL類型不可以轉(zhuǎn)換,但是對(duì)于普通類型來說,可以進(jìn)行轉(zhuǎn)換)

【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言

??16.2.2 函數(shù)模板顯示實(shí)參

  • 一般情況編譯器無法推斷模板實(shí)參類型,此時(shí)需要對(duì)他指定顯示模板實(shí)參

指定顯示模板實(shí)參

'只有實(shí)例化后編譯器才能推導(dǎo)出類型'
template <typename T1, typename T2, typename T3> T1 sum(T2, T3);

'顯示模板實(shí)參'
auto val3 = sum<long long>(i, lng); // T1是顯式指定,T2和T3都是從函數(shù)實(shí)參類型推斷而來
  • 當(dāng)需要給定T3類型時(shí),T1和T2都要提前給,否則會(huì)出錯(cuò),所以對(duì)于這種糟糕的設(shè)計(jì),三個(gè)類型都要顯示給出
    【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言

正常類型轉(zhuǎn)換應(yīng)用于顯示指定的實(shí)參

  • 對(duì)于普通類型定義的函數(shù)參數(shù)可以進(jìn)行正常的轉(zhuǎn)換,同樣對(duì)于模板類型參數(shù)已經(jīng)顯示指定了的函數(shù)實(shí)參,也可以正常的類型轉(zhuǎn)換
    【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言

??16.2.3 尾置返回類型與類型轉(zhuǎn)換

  • 當(dāng)確定返回類型時(shí),可以顯示模板實(shí)參表示模板函數(shù)的返回類型,但是這樣會(huì)增加額外負(fù)擔(dān)。

【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言

  • decltype(*lt)``lt既不是迭代器對(duì)象,也不是指針對(duì)象,只是一個(gè)類型,因此不可以這樣使用
  • decltype(*beg),可以這樣使用,但是在編譯器遇到函數(shù)的列表之前,beg都是不存在的
  • 可以使用尾置返回類型,由于尾置返回出現(xiàn)在參數(shù)列表之后,他可以使用函數(shù)的參數(shù)

??16.2.4 函數(shù)指針和實(shí)參推斷

  • 當(dāng)使用一個(gè)函數(shù)模板初始化一個(gè)函數(shù)指針或?yàn)橐粋€(gè)函數(shù)指針賦值時(shí),編譯器使用指針的類型來推斷模板實(shí)參。
  • 當(dāng)參數(shù)是一個(gè)函數(shù)模板實(shí)例的地址時(shí),程序上下文必須滿足,對(duì)于每個(gè)模板參數(shù)能唯一確定其類型或值
    【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言

??16.2.5 模板實(shí)參推斷和引用

從左值引用函數(shù)參數(shù)推斷類型
【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言
從右值引用函數(shù)參數(shù)推斷類型

  • 從右值引用推導(dǎo),這樣就可以接收右值
template<typename T> void f3(T&&)
f3(42);  //實(shí)參是一個(gè)int類型的右值;模板參數(shù)T是int

引用折疊和右值引用參數(shù)

  • 引用折疊只能應(yīng)用于間接創(chuàng)建引用的引用,如類型別名或模板參數(shù)
  • 引用的引用是不存在的,但是現(xiàn)在有了,只能進(jìn)行引用折疊
  • 只有倆個(gè)都是右值引用才能折疊成右值引用
  • 右值引用既可以接收左值,也可以接收右值

【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言
編寫接收右值引用參數(shù)的模板函數(shù)

template<typename T> void f3(T && val)
{
	T t = val;     //拷貝還是綁定一個(gè)引用
	t = fcn(t);    //賦值只改變t還是既改變t又改變val;
	if(val == t);   //若T是引用類型,則一直是true
}

'對(duì)一個(gè)右值調(diào)用f3時(shí),例如字面值常量42,T為int'
'對(duì)一個(gè)左值i調(diào)用f3時(shí),T為int &,此時(shí)t和val綁定在一起','結(jié)果一直為true'
  • 在實(shí)際中,右值引用通常用于倆種情況:
    • 模板轉(zhuǎn)發(fā)其實(shí)參
    • 模板被重載
'目前使用右值引用的函數(shù)模板通常使用481頁的方式重載'
template <typename T> void f(T&&);  //綁定到非const右值
template <typename T> void f(const T&); //左值和const 右值

??16.2.6 理解std:move

  • move函數(shù)可以將左值引用變?yōu)橛抑狄茫m然不能直接將一個(gè)右值引用綁定到一個(gè)左值,但是用move獲得綁定到左值上的右值引用)

std::move是如何定義的
【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言
std::move是如何工作的

【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言

??16.2.7 轉(zhuǎn)發(fā)

  • 某些函數(shù)需要將一個(gè)或多個(gè)實(shí)參連同類型不變地轉(zhuǎn)發(fā)給其他函數(shù)。因此需要保持轉(zhuǎn)發(fā)實(shí)參的所有性質(zhì),包括實(shí)參類型是否是const的以及實(shí)參是左值還是右值
  • 使用一個(gè)名為forward的新標(biāo)準(zhǔn)庫設(shè)施來傳遞參數(shù),它能夠保持原始實(shí)參的類型。
  • 定義在頭文件utility中。
  • 必須通過顯式模板實(shí)參來調(diào)用。
  • forward返回顯式實(shí)參類型的右值引用。即,forward<T>的返回類型是T&&。

??16.3 重載與模板

  • 函數(shù)模板可以被另一個(gè)模板或一個(gè)普通非模板函數(shù)重載。與普通函數(shù)重載一樣,名字相同的函數(shù)必須具有不同數(shù)量或類型的參數(shù)

編寫重載模板
【c++ primer 筆記】第 16章 模板與泛型編程,C ++ primer,c++,算法,開發(fā)語言

int main()
{
	string s("hi");     
	'模板一更精確'
	cout << debug_rep(s) << endl; //調(diào)用第一個(gè)模板,T類型為string

    '模板二更精確'
	cout << debug_rep(&s) << endl;  //地址可以被封裝成指針,
	//debug_rep(cosnt string*&),由第一個(gè)版本的debug_rep實(shí)例化而來,T被綁定到string *
	//debug_rep( string*),由第二個(gè)版本的debug_rep實(shí)例化而來,T被綁定到string 

     '無法確定,但是根據(jù)規(guī)定,選擇最特化版本'
     const string *sp = &s;
     cout << debug_rep(sp) << endl; //都是精確匹配,但是第二個(gè)更特化
     //debug_rep(cosnt string*&),由第一個(gè)版本的debug_rep實(shí)例化而來,T被綁定到string *
     //debug_rep(cosnt string*),由第二個(gè)版本的debug_rep實(shí)例化而來,T被綁定到const string
}

非模板和模板重載

  • 對(duì)于一個(gè)調(diào)用,如果一個(gè)非函數(shù)模板與一個(gè)函數(shù)模板提供同樣好的匹配,則選擇非模板版本。

??16.4 可變參數(shù)模板

可變參數(shù)模板就是一個(gè)接受可變數(shù)目參數(shù)的模板函數(shù)或模板類。文章來源地址http://www.zghlxwxcb.cn/news/detail-828054.html

  • 可變數(shù)目的參數(shù)被稱為參數(shù)包。
    • 模板參數(shù)包:標(biāo)識(shí)另個(gè)或多個(gè)模板參數(shù)。
    • 函數(shù)參數(shù)包:標(biāo)識(shí)另個(gè)或者多個(gè)函數(shù)參數(shù)。
  • 用一個(gè)省略號(hào)來指出一個(gè)模板參數(shù)或函數(shù)參數(shù),表示一個(gè)包。
  • template <typename T, typename... Args>Args第一個(gè)模板參數(shù)包。
  • void foo(const T &t, const Args& ... rest);rest是一個(gè)函數(shù)參數(shù)包。
  • sizeof...運(yùn)算符,返回參數(shù)的數(shù)目。

??16.4.1 編寫可變參數(shù)函數(shù)模板

  • 可變參數(shù)函數(shù)通常是遞歸的:第一步調(diào)用處理包中的第一個(gè)實(shí)參,然后用剩余實(shí)參調(diào)用自身。

??16.4.2 包擴(kuò)展

  • 對(duì)于一個(gè)參數(shù)包,除了獲取它的大小,唯一能做的事情就是擴(kuò)展(expand)。
  • 擴(kuò)展一個(gè)包時(shí),還要提供用于每個(gè)擴(kuò)展元素的模式(pattern)。

??16.4.3 轉(zhuǎn)發(fā)參數(shù)包

  • 新標(biāo)準(zhǔn)下可以組合使用可變參數(shù)模板和forward機(jī)制,實(shí)現(xiàn)將實(shí)參不變地傳遞給其他函數(shù)。

??16.5 模板特例化

  • 定義函數(shù)模板特例化:關(guān)鍵字template后面跟一個(gè)空尖括號(hào)對(duì)(<>)。
  • 特例化的本質(zhì)是實(shí)例化一個(gè)模板,而不是重載它。特例化不影響函數(shù)匹配。
  • 模板及其特例化版本應(yīng)該聲明在同一個(gè)頭文件中。所有同名模板的聲明應(yīng)該放在前面,然后是特例化版本。
  • 我們可以部分特例化類模板,但不能部分特例化函數(shù)模板。

到了這里,關(guān)于【c++ primer 筆記】第 16章 模板與泛型編程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • STL標(biāo)準(zhǔn)庫與泛型編程(侯捷)筆記6(完結(jié))

    STL標(biāo)準(zhǔn)庫與泛型編程(侯捷)筆記6(完結(jié))

    本文是學(xué)習(xí)筆記,僅供個(gè)人學(xué)習(xí)使用。如有侵權(quán),請(qǐng)聯(lián)系刪除。 參考鏈接 Youbute: 侯捷-STL標(biāo)準(zhǔn)庫與泛型編程 B站: 侯捷 - STL Github:STL源碼剖析中源碼 https://github.com/SilverMaple/STLSourceCodeNote/tree/master Github:課程ppt和源碼 https://github.com/ZachL1/Bilibili-plus 下面是C++標(biāo)準(zhǔn)庫體系結(jié)構(gòu)與內(nèi)核

    2024年01月16日
    瀏覽(15)
  • C++、STL標(biāo)準(zhǔn)模板庫和泛型編程 ——迭代器、 算法、仿函數(shù)(侯捷)

    C++、STL標(biāo)準(zhǔn)模板庫和泛型編程 ——迭代器、 算法、仿函數(shù)(侯捷)

    侯捷 C++八部曲筆記匯總 - - - 持續(xù)更新 ! ! ! 一、C++ 面向?qū)ο蟾呒?jí)開發(fā) 1、C++面向?qū)ο蟾呒?jí)編程(上) 2、C++面向?qū)ο蟾呒?jí)編程(下) 二、STL 標(biāo)準(zhǔn)庫和泛型編程 1、分配器、序列式容器 2、關(guān)聯(lián)式容器 3、迭代器、 算法、仿函數(shù) 4、適配器、補(bǔ)充 三、C++ 設(shè)計(jì)模式 四、C++ 新標(biāo)準(zhǔn) 五、

    2023年04月25日
    瀏覽(34)
  • 【C++】——模板(泛型編程+函數(shù)模板+類模板)

    【C++】——模板(泛型編程+函數(shù)模板+類模板)

    之前我們學(xué)習(xí)了函數(shù)重載,讓我們?cè)趯懴嗨坪瘮?shù)的時(shí)候非常方便,但函數(shù)重載還有很多不足的地方,比如,每次寫相似函數(shù)的時(shí)候,都要我們重新重載一個(gè)邏輯、代碼幾乎一樣的函數(shù),這就導(dǎo)致了我們的效率變低,所以我們今天來學(xué)習(xí)C++模板的相關(guān)知識(shí)點(diǎn),學(xué)習(xí)完模板之后,

    2024年02月05日
    瀏覽(26)
  • C++泛型編程之模板

    C++泛型編程之模板

    目錄 一、什么是泛型編程? 二、函數(shù)模板 2.1函數(shù)模板的概念 2.2函數(shù)模板格式 2.3函數(shù)模板的原理 ?2.5函數(shù)模板的實(shí)例化 2.6模板參數(shù)的匹配原則 三、類模板 3.1類模板的定義格式 3.2 類模板的實(shí)例化 四、非類型模板參數(shù) 五、模板的特化 5.1模板特化的概念: 5.2函數(shù)模板特化 5

    2024年02月07日
    瀏覽(19)
  • 【C++】泛型編程——模板進(jìn)階

    【C++】泛型編程——模板進(jìn)階

    在之前的文章里,我們進(jìn)行了模板初階的學(xué)習(xí)( 【C++】泛型編程——模板初階),了解了什么是泛型編程,學(xué)習(xí)了函數(shù)模板和類模板。 那這篇文章,我們繼續(xù)學(xué)習(xí)模板進(jìn)階的內(nèi)容的學(xué)習(xí)。 首先我們來回顧一下: 我們?cè)谀0宄蹼A的學(xué)習(xí)中,定義模板參數(shù)是怎么定義的? 是不

    2024年02月16日
    瀏覽(19)
  • C++ 泛型編程:函數(shù)模板

    C++ 泛型編程:函數(shù)模板

    當(dāng)需要編寫通用的代碼以處理不同類型的數(shù)據(jù)時(shí),C++ 中的函數(shù)模板是一個(gè)很有用的工具。函數(shù)模板允許我們編寫一個(gè)通用的函數(shù)定義,可以用于多種不同的數(shù)據(jù)類型,從而提高代碼的重用性和靈活性。 泛型編程 是一種編程范式,旨在實(shí)現(xiàn)可重用、通用性高的代碼。它允許我

    2024年02月12日
    瀏覽(19)
  • 【C++】C++泛型編程 | 模板初階

    【C++】C++泛型編程 | 模板初階

    ??????? 個(gè)人主頁:簡(jiǎn) 料 ???? 所屬專欄:C++ ???? 個(gè)人社區(qū):越努力越幸運(yùn)社區(qū) ???? 簡(jiǎn)? ? ?? 介: 簡(jiǎn)料簡(jiǎn)料,簡(jiǎn)單有料~在校大學(xué)生一枚,專注C/C++/GO的干貨分享,立志成為您的好幫手 ~ C/C++學(xué)習(xí)路線 (點(diǎn)擊解鎖) ?? C語言 ?? 初階數(shù)據(jù)結(jié)構(gòu)與算法 ?? C++ ??

    2024年02月08日
    瀏覽(29)
  • 【C++初階】八、初識(shí)模板(泛型編程、函數(shù)模板、類模板)

    【C++初階】八、初識(shí)模板(泛型編程、函數(shù)模板、類模板)

    ========================================================================= 相關(guān)代碼gitee自取 : C語言學(xué)習(xí)日記: 加油努力 (gitee.com) ?========================================================================= 接上期 : 【C++初階】七、內(nèi)存管理 (C/C++內(nèi)存分布、C++內(nèi)存管理方式、operator new / delete 函數(shù)、定位new表

    2024年02月04日
    瀏覽(19)
  • 【C++基礎(chǔ)(十)】C++泛型編程--模板初階

    【C++基礎(chǔ)(十)】C++泛型編程--模板初階

    ??博主CSDN主頁:杭電碼農(nóng)-NEO?? ? ?專欄分類:C++從入門到精通? ? ??代碼倉庫:NEO的學(xué)習(xí)日記?? ? ??關(guān)注我??帶你學(xué)習(xí)C++ ? ???? 在學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)時(shí)會(huì)遇見以下的情況 數(shù)據(jù)結(jié)構(gòu)中存儲(chǔ)的類型往往不能確定 所以在實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)時(shí)往往是這樣做的 在寫代碼時(shí)用DateType來表

    2024年02月13日
    瀏覽(47)
  • 【C++】泛型編程 ② ( 函數(shù)模板與普通函數(shù)區(qū)別 )

    【C++】泛型編程 ② ( 函數(shù)模板與普通函數(shù)區(qū)別 )

    函數(shù)模板與普通函數(shù)區(qū)別 : 主要區(qū)別在于它們能夠處理的 數(shù)據(jù)類型數(shù)量 和 靈活性 ; 自動(dòng)類型轉(zhuǎn)換 : 函數(shù)模板 不允許 自動(dòng)類型轉(zhuǎn)化 , 會(huì)進(jìn)行嚴(yán)格的類型匹配 ; 普通函數(shù) 能夠進(jìn)行 自動(dòng)類型轉(zhuǎn)換 , 內(nèi)含隱式的類型轉(zhuǎn)化 ; 參數(shù) / 返回值 數(shù)據(jù)類型 : 普通函數(shù) 只接受 特定類型 參數(shù)

    2024年02月20日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包