mam niewiarygodnie ekscytujące bibliotekę, która może przełożyć punktów: powinien działać ze wszystkimi rodzajami punktowychJak rozwiązać dwuznaczność w przeciążonych funkcji wykorzystujących SFINAE
template<class T>
auto translate_point(T &p, int x, int y) -> decltype(p.x, p.y, void())
{
p.x += x;
p.y += y;
}
template<class T>
auto translate_point(T &p, int x, int y) -> decltype(p[0], void())
{
p[0] += x;
p[1] += y;
}
translate_point
będzie współpracować z punktami, które mają publiczne x
i y
członków, i będzie również działać z krotkami/zmiennymi pojemnikami, gdzie x
i y
są reprezentowane odpowiednio przez pierwszy i drugi element.
Problemem jest inna biblioteka definiuje klasę punkt o publicznym x
i y
, ale również umożliwia indeksowanie:
struct StupidPoint
{
int x, y;
int operator[](int i) const
{
if(i == 0) return x;
else if(i == 1) return y;
else throw "you're terrible";
}
};
Moja aplikacja, za pomocą obu bibliotek, jest następujący:
int main(int argc, char **argv)
{
StupidPoint stupid { 8, 3 };
translate_point(stupid, 5, 2);
return EXIT_SUCCESS;
}
ale to powoduje, że GCC (i klang) są nieszczęśliwe:
error: call of overloaded ‘translate_point(StupidPoint&, int, int)’ is ambiguous
Teraz widzę, dlaczego tak się dzieje, ale chcę wiedzieć, jak to naprawić (zakładając, że nie mogę zmienić wewnętrznych ustawień StupidPoint), a jeśli nie ma łatwego rozwiązania, to jak mogę jako wykonawca biblioteki zrobić to łatwiej się z tym uporać.
W którym przypadku chcesz zadzwonić? –
W tym przypadku pierwsza wersja, ponieważ jest (przynajmniej teoretycznie) nieco szybsza. Również 'operator []' ma również niestałe przeciążenie zwracające 'int &', które pominąłem w moim prostym przypadku testowym. – jaymmer