如果i
是一個int,那麼第一個是不可行的。最後兩個保持。然後,爲了扣除i
,第二個和第三個產生用於重載分辨率的相同功能類型(作爲參數int&
)。所以你必須依靠部分排序。
但是,部分排序無法區分它們。對於函數調用部分排序上下文,只有參數用於確定一個順序(並且不考慮示例中的返回類型),並且任何引用修飾符都從它們中剝離。因此,您將成功推導出兩個方向上的參數類型 - 兩種參數類型都至少與其他參數相同。而且const也沒有應用,所以都不是比其他更專業。
有一個問題報告佔位符,旨在澄清與部分排序中的右值/左值引用困難相關的任何事情。詳細信息請參見this usenet question。
如果兩者中的任何一個應該更專業化,我會說它應該是第一個。畢竟,它比另一個接受更少的論據(另一個是潛在的完美的貨運代理)。
特別是由於T1 & &不會綁定到左值,除非我明確前進/移動。
其實,它會接受任何東西。在模板中有一個T&&
類型的參數將切換到「perfect-forwarding-deduction-mode」,它將推斷T
參數的類型,如果它是一個右值,並且將一個左值引用修改器添加到類型T
如果它是一個左值。因此,如果參數是一個左值,則生成的參數類型爲T& &&
摺疊爲T&
,它接受很好的左值(就像你的情況一樣)。
第二次看,你似乎試圖做的是重載一個函數,通過移動它們來獲取對象。但是由於T&&
(見下文)的特殊扣除,這將不起作用。只是擦除第一功能和編寫代碼爲
template<typename T, typename T1> T* Push(T1&& ref) {
/* for lvalues, T1 is U& and rvalues it is U, with U being the
* argument type. */
T t1(std::forward<T1>(ref));
/* whatever needs to be done ... */
}
這將布展構建t1
如果參數是一個右值,並複製ref
如果參數是一個左值或者T
不具有移動構造函數。這只是一個例子,根據你的實際用例,它可能不是你應該做的。我也不確定你爲什麼在這裏有兩個模板參數類型。我建議擺脫T
,並說typename remove_reference<T1>::type *
爲返回類型,而不是。這樣你可以從爭論中扣除。
我不知道'我'是什麼? – 2010-06-06 15:24:51
「我」是什麼類型?你正在使用哪種編譯器?如果錯誤的函數被調用,如果編譯器說它是不明確的(那麼它應該只是產生一個錯誤)? – jalf 2010-06-06 15:28:21