template <typename T>
void function(T&& arg)
詳細有人能解釋它是如何結束這個函數簽名換成T &爲左值和T & &爲右值傳入?我知道,不知何故(標準線需要)T - > T &在左值的情況下,T - > T在重估的情況下,然後通過組合&和& &它結果左值/右值引用。
template <typename T>
void function(T&& arg)
詳細有人能解釋它是如何結束這個函數簽名換成T &爲左值和T & &爲右值傳入?我知道,不知何故(標準線需要)T - > T &在左值的情況下,T - > T在重估的情況下,然後通過組合&和& &它結果左值/右值引用。
該規則在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)
這要歸功於參考崩潰規則。假設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)
來創建與您的函數調用的表達式相同的表達式。
看起來每一行代表一個一致的集合,如果表使用'T1' ...'T3',也許會有所幫助。 – aschepler
@Xeo:我已經說明了它。 –
不是真的重複,但http://stackoverflow.com/questions/3582001/advantages-of-using-forward有答案。 – pmr
實際上,在rvalues的情況下,T→T。我強烈建議觀看[Scott Meyers關於這個特定主題的視頻](http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Scott-Meyers-Universal-References-in -Cpp11)。 – Xeo
我也推薦閱讀[我的這個答案](http://stackoverflow.com/a/8527373/500104)一步一步解釋如何扣除和參考崩潰的作品。 – Xeo