2013-05-04 33 views
4

我知道,給定一個初始化轉發/通用參考的表達式,左值被推斷爲類型T &和類型T的右值(而不是T & &)。爲什麼在右值的情況下轉發引用不會導致右值引用?

因此,只允許右值,一個需要寫

template<class T, enable_if<not_<is_lvalue_reference<T> >,OtherConds... > = yes> 
void foo(T&& x) {} 

,而不是,

template<class T, enable_if<is_rvalue_reference<T>,OtherConds... > = yes> 
void foo(T&& x) {} 

我的問題是,爲什麼轉發引用,右值被推斷爲T型和不是T&&?我想,如果他們被推斷爲T & &然後也同樣參照崩潰規則可以作爲T&& &&是一樣T&&

+0

'enable_if ,...>'會起作用。 :)至於爲什麼它被推斷爲'T' - 因爲這是它與左值引用一起工作的方式? 'T&' - >'U'參數 - >'U&'。這是一個特殊的左值情況,而不是右值情況。 – Xeo 2013-05-04 11:45:01

回答

2

因爲在那個時候,演繹右值A參數爲A&&,而不是A被視爲從扣除的一般規則不必要的併發症和離開:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm

我們真的沒甚至不知道我們是否可以得到扣除規則的一個例外(對於左值A的情況),我們甚至從來沒有想到我們會要求兩個例外。要做到這一點,其好處將是:它使不可能的,可能的。

畢竟,沒有了左值情況下,單一的特殊扣規則,完善轉移是不可能的,因爲N1385恰如其分地證明。

即使今天回想起來,增加一個特殊扣規則,使客戶能夠避免否定模板約束,似乎並不像一個很高的效益/成本比。特別是與2002年我們拍攝的效益/成本比較。

+0

我已通過這些文件了,也爲完美轉發其他一些特殊的語法,但從來沒有爲什麼它被選爲'T'而不是'T清醒的認識&&'。通過N1385去,甚至建議#7說,有關參考崩潰,並說「推斷A1的引用類型,當參數是一個左值,否則非引用類型」,但沒有給予任何理由爲什麼不右值引用類型,否則。我只是好奇,想了解歷史,我'T &&'扣除,而不是'T'看上去更對稱,而且看起來也適用於所有情況,包括'的std :: forward' – abir 2013-05-04 17:19:02

+0

是的,我同意,我認爲這會工作。但是額外的改變很可能會導致委員會接受「太多改變」。它可能會使C++ 11中的rvalue-refs脫軌。而且沒有動機冒這個險。 – 2013-05-04 18:56:48

相關問題