Wie Mehrdeutigkeiten in überladenen Funktionen mit SFINAE @ behoben werden könn
Ich habe eine unglaublich aufregende Bibliothek, die Punkte übersetzen kann: Sie sollte mit allen Punkttypen funktionieren.
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
wird mit Punkten arbeiten, die public @ habx
undy
-Mitglieder, und es wird auch mit Tupeln / indizierbaren Containern funktionieren, bei denenx
undy
wird durch das erste bzw. zweite Element dargestellt.
Das Problem ist, eine andere Bibliothek definiert eine Punktklasse mit publicx
undy
, erlaubt aber auch die Indizierung:
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";
}
};
Meine Anwendung, die beide Bibliotheken verwendet, ist die folgende:
int main(int argc, char **argv)
{
StupidPoint stupid { 8, 3 };
translate_point(stupid, 5, 2);
return EXIT_SUCCESS;
}
aber das macht GCC (und clang) unglücklich:
error: call of overloaded ‘translate_point(StupidPoint&, int, int)’ is ambiguous
Nun kann ich nachvollziehen, warum dies geschieht, aber ich möchte wissen, wie dies behoben werden kann (vorausgesetzt, ich kann die Interna von StupidPoint nicht ändern) und, falls es keine einfache Lösung gibt, wie ich dies als Bibliotheksimplementierer tun könnte einfacher zu handhaben.