Operatoren-Vererbung bei generischer Vererbung



  • Hi, folgender Code liefert bei mir falsche Resultate (VC8) bzw. kompiliert gar nicht erst (GCC4):

    template <typename D>
    struct Base {
        virtual D& operator ++() = 0;
        D operator ++(int)
        {
            D ret = *dynamic_cast<D*>(this);
            ++*this;
            return ret;
        }
        virtual ~Base() { }
    };
    
    struct Derived : Base<Derived> {
        Derived() : m_value() { }
    
        Derived& operator ++()
        {
            ++m_value;
            return *this;
        }
    
        int operator *() const { return m_value; }
    
    private:
        int m_value;
    };
    
    int main()
    {
        Derived d;
        cout << *d++ << endl;
    }
    

    Angeblich wird kein Postfix-op++ gefunden. Komisch, ich sehe ihn doch aber. Wieso erbt 'Derived' den Operator denn nicht? Wo liegt mein Fehler?

    (PS: VC8 warnt, verwendet aber den Präfix-op++, d.h. die Ausgabe des Codes ist "1", ich hätte aber "0" erwartet und gewollt. Es nützt übrigens nichts, den Postfix-op++ virtuell zu machen.)

    /EDIT: Einmal "Vererbung" im Titel entfernt. :-p



  • Hallo,
    das Ganze hat nichts mit Templates zu tun, sondern schlicht mit der Art und Weise, wie Überladung funktioniert. Da in derived ein operator++ existiert, wird kein weiterer Scope mehr nach einem op++ durchsucht, d.h. die Kandidatenmenge für die Überladungsauflösung enthält nur den op++ aus derived. Dieser besitzt aber die Prefix-Form und ist damit kein gültiger Kandidat für den Aufruf -> Fehler.

    Lösung: Eine using-Deklaration in derived:

    struct Derived : Base<Derived> {
        Derived() : m_value() { }
        using Base<Derived>::operator++;
        Derived& operator ++()
        {
            ++m_value;
            return *this;
        }
    
        int operator *() const { return m_value; }
    
    private:
        int m_value;
    };
    

    Ausführlicher: http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs&faq=Overload#Answ



  • HumeSikkins schrieb:

    Da in derived ein operator++ existiert, wird kein weiterer Scope mehr nach einem op++ durchsucht

    Lol. Wie konnnte ich das bloß vergessen ...

    Na ja, vielen Dank. 🙂


Anmelden zum Antworten