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.

Antworten auf die Frage(8)

Ihre Antwort auf die Frage