2012-10-23 45 views
1

對於例如模板參數推導 - T被推導和T &&使用

template <typename T> 
void function(T&& arg) 

詳細有人能解釋它是如何結束這個函數簽名換成T &爲左值和T & &爲右值傳入?我知道,不知何故(標準線需要)T - > T &在左值的情況下,T - > T在重估的情況下,然後通過組合&和& &它結果左值/右值引用。

+0

不是真的重複,但http://stackoverflow.com/questions/3582001/advantages-of-using-forward有答案。 – pmr

+2

實際上,在rvalues的情況下,T→T。我強烈建議觀看[Scott Meyers關於這個特定主題的視頻](http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Scott-Meyers-Universal-References-in -Cpp11)。 – Xeo

+1

我也推薦閱讀[我的這個答案](http://stackoverflow.com/a/8527373/500104)一步一步解釋如何扣除和參考崩潰的作品。 – Xeo

回答

4

該規則在8.3.2p6節中找到。

如果一個typedef,一個類型模板參數decltype說明符表示類型TR 即一種類型T的引用,試圖創建類型「左值參考cvTR「創建類型」左值引用爲T「,而嘗試創建類型」右值引用cvTR「創建類型TR

或者以表格的形式:

TR R 

T& & -> T& // lvalue reference to cv TR -> lvalue reference to T 
T& && -> T& // rvalue reference to cv TR -> TR (lvalue reference to T) 
T&& & -> T& // lvalue reference to cv TR -> lvalue reference to T 
T&& && -> T&& // rvalue reference to cv TR -> TR (rvalue reference to T) 
+0

是的,但你如何解釋T是T&T是T &&。對於左值(不管是類型參考還是簡單值),T是T&? – Ghita

+0

我認爲這裏缺少的是模板參數演繹如何在這個過程中發揮作用。 – Xeo

+0

@Ben萬一我沒有弄明白。爲了適用第8.3節。2p6你必須說第一個T是T或T是T - >構成爲&和&& – Ghita

4

這要歸功於參考崩潰規則。假設U是非參考類型;然後:

T = U    T & = U &  T && = U && 
If T = U & , then T & = U & and T && = U & . 
    T = U &&   T & = U &  T && = U && 

因此,如果你的函數參數可以綁定到U類型的左值引用,那麼T必須去­ duced爲U &爲了T &&成爲U &,這是唯一的選擇,因爲左值不能綁定到右值引用。另一方面,如果您的參數是U類型的右值,那麼T是de ­,作爲U,因此T &&變爲U &&,您的參數可以綁定。

關鍵是匹配參考類型是T &&(而不是T!)。但是,由於arg本身是一個已命名的變量,因此它是一個左值,因此必須使用std::forward<T>(arg)來創建與您的函數調用的表達式相同的表達式

+0

看起來每一行代表一個一致的集合,如果表使用'T1' ...'T3',也許會有所幫助。 – aschepler

+1

@Xeo:我已經說明了它。 –