讓foo
是函數:理解型扣除普遍引用
template< typename T >
void foo(T&& a){}
什麼類型將T
推斷爲foo
以下呼叫:
foo(0); // is T here int or int&& ?
int a = 0;
foo(a); // is T here int or int& ?
讓foo
是函數:理解型扣除普遍引用
template< typename T >
void foo(T&& a){}
什麼類型將T
推斷爲foo
以下呼叫:
foo(0); // is T here int or int&& ?
int a = 0;
foo(a); // is T here int or int& ?
的類型推演默認規則參考類型永遠不可能是扣除的結果。給定此代碼,
template <class T>
void bar(T par);
bar(0);
int a;
bar(a);
int &b;
bar(b);
所有3個電話將呼叫foo<int>
。也就是說,T
推導爲int
而par
的類型爲int
。
轉發的引用通過簡單添加一個規則的工作:當用於一個轉發參考的類型扣(即,參數T&&
的用於推導T
)參數是X
類型的左值,類型X &
用於代替X
進行扣除。
請注意,這意味着給定類型X
,只有X
或X &
可以是類型扣除的結果; X &&
永遠不會。
讓我們來分析你的代碼(我將重新命名,他功能參數,使之清楚,我指):
template <class T>
void foo(T &&par);
foo(0);
int a;
foo(a);
在第一種情況下foo(0)
,參數是int
類型的右值因此使用類型int
來進行類型推斷,這意味着T
被推導爲int
(被稱爲的函數是foo<int>
)並且par
的類型是int &&
。
在第二種情況foo(a)
中,自變量是值類型int
。轉發參考規則將啓動並使用類型int &
進行推導。 T
因此推導爲int &
(函數名爲foo<int&>
),並且par
的類型爲「int & &&
」,其摺疊爲int &
。
foo(0); //是T這裏是int還是int & &?
安int
。
int a = 0; (a); //是T這裏int還是int &?
一個int&
。
像您
template< typename T >
void foo(T&& a){}
什麼在推斷上下文表達T&&
即T的基礎上,提供的參數推斷,是受 reference collapsing rules。
總之;
如果所提供的參數是一個左值type
類型的,T&&
將擴大到type& &&
坍塌到type&
如果所提供的參數是type
類型的右值,T&&
將展開至type &&
,摺疊至type&&
注意,兩者都是引用,如果你需要觸發另一個函數的右值 超載,你需要做的std::forward<T>(a)
您可以通過使用不同類型的特徵,如HTTP嘗試:// EN。 cppreference.com/w/cpp/types/is_reference或std :: is_same ..並用std :: add_lvalue_reference之類的東西建立類型,然後看看這些特徵的值是什麼 – xaxxon
下面是一個例子,所以你可以看到一種方式自己測試一下:https://wandbox.org/permlink/51APJ9Pr4fsweWrF – xaxxon
這裏有一個調試類型的技巧:'template class TD;',然後在foo中使用:'TD ();'。由於'TD'沒有定義,編譯器會發出抱怨,並且在錯誤消息中,一個好的編譯器會顯示'T'的類型。 –
geza