C++ Primer 5th笔记(chap 16 模板和泛型编程)模板实参推断和引用
template < typename T> void f (T &p)
函數(shù)參數(shù)p是一個(gè)模板類(lèi)型參數(shù)T的引用, 編譯器會(huì)應(yīng)用正常的引用綁定規(guī)則; const 是底層的, 不是頂層的
1.1 從左值引用函數(shù)參數(shù)推斷類(lèi)型
函數(shù)參數(shù)的類(lèi)型
- 一個(gè)普通( 左值) 引用時(shí)( 形如 T & )
綁定規(guī)則:傳遞一個(gè)左值( 一個(gè)變量或一個(gè)返回引用類(lèi)型的表達(dá)式)。實(shí)參可以是 const 類(lèi)型, 也可以不是。
如果實(shí)參是 const 的, 則 T 將被推斷為 const 類(lèi)型: template <typename T> void f1 ( T& ) ; / / 實(shí)參必須是一個(gè)左值/ / 對(duì) fl 的調(diào)用使用實(shí)參所引用的類(lèi)型作為模板參數(shù)類(lèi)型 fl (i); / / i 是一個(gè)int; 模板參數(shù)類(lèi)型 T 是 int fl (ci) ; // ci 是一個(gè) const int; 模板參數(shù) T 是 const int fl (5 ); / / 錯(cuò)誤: 傳遞給一個(gè)&參數(shù)的實(shí)參必須是一個(gè)左值-
const T&
綁定規(guī)則:可以傳遞給它任何類(lèi)型的實(shí)參 個(gè)對(duì)象( const 或非 const)、 一個(gè)臨時(shí)對(duì)象或是一個(gè)字面常量值。 -
函數(shù)參數(shù)本身是 const 時(shí),T 的類(lèi)型推斷的結(jié)果不會(huì)是一個(gè)const類(lèi)型。 const已經(jīng)是函數(shù)參數(shù)類(lèi)型的一部分; 因此, 它不會(huì)也是模板參數(shù)類(lèi)型的一部分:
1.2 從右值引用函數(shù)參數(shù)推斷類(lèi)型
當(dāng)一個(gè)函數(shù)參數(shù)是一個(gè)右值引用(形如 T &&)
綁定規(guī)則:傳遞給它一個(gè)右值。 類(lèi)型推斷過(guò)程類(lèi)似普通左值引用函數(shù)參數(shù)的推斷過(guò)程。 推斷出的 T 的類(lèi)型是該右值實(shí)參的類(lèi)型:
template <typename T> void f3 (T &&) ; f3 (42) ; // 實(shí)參是一個(gè) int 類(lèi)型的右值; 模板參數(shù) T 是 int1.3 引用折疊和右值引用參數(shù)
假定i是一個(gè) int 對(duì)象, 我們可能認(rèn)為像 f3(i) 這樣的調(diào)用是不合法的。 畢竟,i是一個(gè)左值, 而通常我們不能將一個(gè)右值引用綁定到一個(gè)左值上。 但 C++語(yǔ)言在正常綁定規(guī)則之外定義了兩個(gè)例外規(guī)則, 允許這種綁定。
1.3.1規(guī)則1
影響右值引用參數(shù)的推斷如何進(jìn)行。 當(dāng)我們將一個(gè)左值( 如i) 傳遞給函數(shù)的右值引用參數(shù), 且此右值引用指向模板類(lèi)型參數(shù)( 如 T &&) 時(shí), 編譯器推斷模板類(lèi)型參數(shù)為實(shí)參的左值引用類(lèi)型。 因此, 當(dāng)我們調(diào)用 f3(i)時(shí), 編譯器推斷 T 的類(lèi)型為int&,而非int。
T 被推斷為 int &看起來(lái)好像意味著 f3 的函數(shù)參數(shù)應(yīng)該是一個(gè)類(lèi)型int &的右值引用。
1.3.2 規(guī)則2
如果我們間接創(chuàng)建一個(gè)引用的引用, 則這些引用形成了‘‘ 折疊”。 在所有情況下( 除了一個(gè)例外), 引用會(huì)折疊成一個(gè)普通的左值引用類(lèi)型。 在新標(biāo)準(zhǔn)中, 折疊規(guī)則擴(kuò)展到右值引用。 只在一種特殊情況下引用會(huì)折疊成右值引用: 右值引用的右值引用。 即, 對(duì)于一個(gè)給定類(lèi)型 X:
- X & &、 X & & &和 X & & &都折疊成類(lèi)型 X &
- 類(lèi)型 X & & & &折疊成 X & &
當(dāng)一個(gè)模板參數(shù) T 被推斷為引用類(lèi)型時(shí), 折疊規(guī)則告訴我們函數(shù)參數(shù) T & &折疊為一個(gè)左值
引用類(lèi)型。 例如, f3 (i) 的實(shí)例化結(jié)果可能像下面這樣:
f3 的函數(shù)參數(shù)是 T&&且 T是int&, 因此T&&是int&&&, 會(huì)折疊成int&。 因此, 即使f3 的函數(shù)參數(shù)形式是一個(gè)右值引用(即T&&), 此調(diào)用也會(huì)用一個(gè)左值引用類(lèi)型(即int&) 實(shí)例化 f3:
void f3<int&> (int & ); // 當(dāng) T 是 int &時(shí), 函數(shù)參數(shù)折疊為 int &這兩個(gè)規(guī)則導(dǎo)致了兩個(gè)重要結(jié)果:
? 如果一個(gè)函數(shù)參數(shù)是一個(gè)指向模板類(lèi)型參數(shù)的右值引用( 如T&&), 則它可以被綁定到一個(gè)左值;
? 如果實(shí)參是一個(gè)左值, 則推斷出的模板實(shí)參類(lèi)型將是一個(gè)左值引用, 且函數(shù)參數(shù)將被實(shí)例化為一個(gè)( 普通) 左值引用參數(shù)(T &)
另外值得注意的是, 這兩個(gè)規(guī)則暗示, 我們可以將任意類(lèi)型的實(shí)參傳遞給 T&&類(lèi)型的函數(shù)參數(shù)。 對(duì)于這種類(lèi)型的參數(shù), ( 顯然) 可以傳遞給它右值, 而如我們剛剛看到的, 也可以傳遞給它左值
總結(jié)
以上是生活随笔為你收集整理的C++ Primer 5th笔记(chap 16 模板和泛型编程)模板实参推断和引用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: cmake (0)简介
- 下一篇: EOS 智能合约源代码解读 (3)ass