Mam funkcję, która może akceptować dowolny typ według uniwersalnego odwołania i chciałbym ją przeciążać dla określonych typów (niektóre z nich sami są szablonami, chociaż nie sądzę, że jest to ważne). Niestety, wydaje mi się, że nie udało mi się usunąć przeciążeń w odpowiedniej kolejności.Rozdzielczość przeciążeniowa z odwołaniami uniwersalnymi
Przypuszczam, że druga deklaracja foo
byłaby preferowana, ponieważ jest bardziej szczegółowa (mniej szablonowa), chociaż wygląda na to, że brakuje mi nieco zrozumienia dla rozwiązania dotyczącego przeciążenia. Co ciekawe, zmiana drugiej deklaracji na wartość X
według wartości powoduje, że jest drukowana "dobra, dobra", co powoduje, że jest ona "niezła, dobra". Oczywiście usunięcie pierwszej deklaracji całkowicie powoduje, że zwraca ona "dobry, dobry", ponieważ nie ma innego wyboru.
Dlaczego tak się dzieje? A co najważniejsze, jeśli poniższy kod nie działa, jak można przeciążać funkcję tym podpisem?
#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;
}
Edit:
Może bardziej rondo Rozwiązaniem tego problemu jest zrobić to w sposób pośredni. Pozbądź się pierwszej formy foo
i użyj SFINAE, aby sprawdzić, czy istnieje przeciążenie, ale nie zadzwoń pod foo_fallback
.
mam wymyślić rozwiązanie przeciążenia części: http://mortoray.com/2013/06/03/overriding-the-broken-universal-reference-t/ –
1 + godzina [youtube video] (https://www.youtube.com/watch?v=T5swP3dr190) w sprawie tego problemu, który z łatwością łączy się z tym pytaniem. – Yakk