如何理解c 中的引用摺疊

2021-07-30 05:22:29 字數 1360 閱讀 1960

感覺上叫引用坍塌好理解點(reference-collapsing rules)

就這樣a& & 變成 a&

a& && 變成 a&

a&& & 變成 a&

a&& && 變成 a&&

就是左值引用會傳染,只有純右值&& && = &&,沾上乙個左值引用就變左值引用了

引用摺疊的規則上面的各位已經說得很清楚了,我在這裡補充下引用摺疊是為什麼出現的吧。

要說引用摺疊,首先得說右值引用(在看這個之前需要了解c++11中左值,右值的概念)。它是c++11出現的新概念,宣告型別的方法是:t&&,具體資訊可以看下面的**:

classa};

ageta

()int

main

()

a1是左值,在構造時使用了geta() 產生的臨時物件,之後geta()產生的臨時物件會銷毀。

a2是右值引用,其指向的就是geta()所產生的物件,這個物件的宣告週期是和a2的宣告週期是一致的。即少了臨時物件,從而省去了臨時物件的構造和析構。

由此可見右值引用的好處,在新**中,右值引用是值得大力使用的。但是,在使用的時候,有例外情況了:t&&並不是一定表示右值,比如,如果它繫結的型別是未知的話,既可能是左值,又可能是右值。比如:

template

<

typename

t>

voidf(

t&¶m);f

(10);// 10是右值

intx=10

;f(x

);// x是左值

以上這種未定的引用型別(param的型別)稱為 universal references,這種型別必須被初始化,而它是左值還是右值則取決於它的初始化,如果被左值初始化,那麼它就是左值,反之亦然。那麼什麼時候是左值,什麼時候是右值,就需要進行型別推導才知道。

由於存在t&&這種未定的引用型別,當它作為引數時,有可能被乙個左值引用或右值引用的引數初始化,這是經過型別推導的t&&型別,相比右值引用(&&)會發生型別的變化,這種變化就稱為引用摺疊。(《深入應用c++11-**優化與工程級應用》 --- 祁宇 p68 )

引用摺疊的規則如下(配合@jun-jun的答案)[和上一段的出處一樣]:

1.所有右值引用摺疊到右值引用上仍然是乙個右值引用。(a&& && 變成 a&&)

2.所有的其他引用型別之間的摺疊都將變成左值引用。 (a& & 變成 a&; a& && 變成 a&; a&& & 變成 a&)

以上,才疏學淺,有不明確或不正確的地方,請指正。

C 的引用摺疊

引用摺疊 建立引用的引用時 如模板引數 型別別名 會造成引用摺疊,摺疊規則如下 1.2.3.左值 非引用 模板形參的 實際上是 編譯器會自己在模板形參型別前加 這樣就變成了 依據前面的規則還是會摺疊為 注意 第3種情況只適用於 形參的模板函式,不適合普通函式!例子 templatet ff t x ...

C 右值引用和引用摺疊

當我們將乙個左值傳遞給右值引用引數時,且此右值引用指向模板型別引數 t 時,編譯器推斷模板型別引數為左值引用型別而非左值。當我們間接建立乙個引用的引用,如型別別名或模板引數,則這些引用形成了摺疊 因為有上述兩個規則,所以如果乙個函式引數是指向模板引數型別的右值引用,則可以傳遞給它任意型別的實參。如果...

C 中的引用(記錄 理解)

type name var int main 注意 普通引用在宣告時,必須用其他的變數進行初始化 不能用常量進行初始化 swap函式的實現對比 void swap int a,int b swap a,b void swap int pa,int pb swap a,b 注意 引用作為函式引數宣告時...