2016-11-11 40 views
0

有人可以幫助我理解爲什麼下面的代碼型扣,而使用通用引用

template< typename T > 
void check() 
{ 
    std::cout << "unknow type" << std::endl; 
} 

template<> 
void check<int>() 
{ 
    std::cout << "int" << std::endl; 
} 

template<> 
void check<int&>() 
{ 
    std::cout << "int&" << std::endl; 
} 

template<> 
void check<int&&>() 
{ 
    std::cout << "int&&" << std::endl; 
} 

template< typename T > 
void bar(T&& a) 
{ 
    check<T>(); 
} 

int main() 
{ 
    bar(0); 

    int a = 0; 
    bar(a); 
} 

的輸出

int 
int& 

,而不是

int&& 
int& 

從我的觀點。看來,r值參考仍然是一個r值參考值和一個l值參考值alue引用,但是,似乎只有l值引用保留爲l值引用,r值變爲非引用值。 這背後的動機是什麼?

+5

您正在使用'check ',而不是'檢查';爲什麼您希望'&&'在您明確省略時出現? – ildjarn

+0

我預計'bar(0)'與'(0)'相同。當用'bar (0)'在我的代碼中替換'bar(0)'時,輸出實際上是'int && \ n int&'。 –

+3

「酒吧」的類型爲「無效(T &&)」,「酒吧」的類型爲「無效(T && &&)」(在參考摺疊之前)。 – Oktalist

回答

4

bar(0);調用專業化bar<int>(int&&)T推導爲int,所以check<T>()check<int>()是。參數類型爲T&&,即int&&,但這是參數的類型,而不是類型T

這與非轉發參考完全一致。如果定義:

template<typename T> void baz(T&); 

和你int類型,然後的一個左T被推斷爲int,不int&

這是特別的喜歡你的例子使用轉發引用的唯一的事情稱之爲是爲T&&該類型可以推斷爲左值參考,稱之爲R,在這種情況下,參數類型爲R&&,與add_rvalue_reference_t<R>相同,這只是R。所以對於通話bar(a)調用專業化bar<int&>(int&)T被推斷爲int&

當你調用bar<int&&>(0)有一個明確的模板參數列表沒有參數扣等Tint&&取代,因此參數類型T&&add_rvalue_reference_t<int&&>這只是int&&