3 Stimmen

C++ Teilerbestellung scheitert mit 2 Template-Parametern

Angenommen, die folgenden Template-Funktionen mit partieller Spezialisierung:

template
void foo(vector &in) {
    cout << "Vektor" << endl;
}

template
void foo(T &in) {
    cout << "Skalar" << endl;
}

int main(int arc, char *argv[]) {
    vector a;
    double b;

    foo(a);
    foo(b);
    return 0;
}

Ich habe kein Problem beim Kompilieren mit g++ 3.4.6 und erhalte die erwartete Ausgabe:

Vektor
Skalar

Jetzt, wenn ich einen zweiten Template-Parameter hinzufüge:

template
void foo2(vector &in) {
    U a;
    cout << "Vektor" << endl;
}

template
void foo2(T &in) {
    U a;
    cout << "Skalar" << endl;
}

und es mit folgendem aufrufe:

int main(int arc, char *argv[]) {
    vector a;
    double b;

    foo2(a);
    foo2(b);
    return 0;
}

Wenn ich versuche, es zu kompilieren, gibt mir GCC 3.4.6 einen Fehler mit einer Mehrdeutigkeit bei der Überladung:

Fehler: Aufruf von Überladung `foo2(std::vector >&)' ist mehrdeutig
Notiz: Die Kandidaten sind: void foo2(std::vector >&) [with U = double, T = double]
Notiz:                 void foo2(T&) [with U = double, T = std::vector >]

Ich verstehe nicht, wie der zweite Template-Parameter die Überladung jetzt mehrdeutig macht. Soweit ich weiß, sollte die Vektorversion immer noch spezialisierter sein. Ist das nur ein Fehler in 3.4? Gibt es eine Lösung?

Zur Information, der Code funktioniert in gcc 4.1 ohne Probleme. Leider sind einige unserer Tools immer noch an 3.4 gebunden, sodass ein Upgrade nicht die Lösung ist.

Danke.

2voto

Kirill V. Lyadvinsky Punkte 92957

Dies scheint mit diesem Defekt zusammenhängen, der in der neuesten Version des Compilers behoben ist. Workarounds sind entweder alle Argumente des Templates explizit festzulegen oder anstelle dessen einen Funktor zu verwenden:

template
struct foo2 {
    template
    void operator()( std::vector &in ) {
        U a;
        cout << "Vektor" << endl;
    }
    template
    void operator()( T& in ) {
        U a;
        cout << "Skalar" << endl;
    }
};

int main(int arc, char *argv[]) {
    vector a;
    double b;

    foo2()(a);
    foo2()(b);
    return 0;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X