我有一個函數可以通過通用引用接受任何類型,並且希望爲特定類型重載它(其中一些模板本身是模板化的,儘管我認爲這並不重要)。不幸的是,我似乎不太可能讓重載以正確的順序得到解決。帶有通用引用的重載分辨率
我會假設foo
的第二個聲明是首選,因爲它更具體(模板較少),儘管看起來我對重載分辨率的理解還是有些欠缺。有趣的是,將第二個聲明更改爲X
的值會使其打印出「好,好」,並通過非const引用使其成爲X
,使其打印出「不好,很好」。顯然,刪除第一個聲明完全使它返回「好,好」,因爲沒有別的選擇。
那麼爲什麼會發生這種情況呢?最重要的是,如果下面的代碼不起作用,那麼如何用這個簽名重載一個函數?
#include <iostream>
#include <string>
class X {};
template<typename T>
inline std::string foo(T && rhs) {
return "bad";
}
inline std::string foo(const X & rhs) {
return "good";
}
int main() {
std::cout << foo(X()) << std::endl;
X x;
std::cout << foo(x) << std::endl;
return 0;
}
編輯:
也許更迂迴的解決方案,這是間接地做到這一點。擺脫foo
的第一種形式,並使用SFINAE檢查是否存在有效的過載,然後它不會調用foo_fallback
。
我想出了一個解決超載部分:http://mortoray.com/2013/06/03/overriding-the-broken-universal-reference-t/ –
1 +小時[youtube video](https://www.youtube.com/watch?v=T5swP3dr190)對這個確切的問題,這有趣地鏈接回到這個問題。 – Yakk