template über verschachtelte klassen mit ostream-operator



  • Hallo,

    ich hoffe das Problem lässt sich gut an dem Code nachvollziehen, fällt mir immer schwer sowas zu erklären:

    #include <iostream>
    using namespace std;
    
    template<class T>
    struct tree {
        struct node {
            virtual ostream& write(ostream& out) const = 0;
        };
    
        struct item : public node {
            ostream& write(ostream& out) const;
        };
    };
    
    template<class T>
    ostream& operator<<(ostream& out, const typename tree<T>::node& n) {
        return n.write(out);
    }
    
    template<class T>
    ostream& tree<T>::item::write(ostream& out) const {
        return out;
    }
    
    int main() {
        tree<int>::item i;
        cout << i;
    }
    

    Leider wird kein <<-operator gefunden.
    Wie macht man das?

    Danke



  • sollte eigentlich so funktionieren...

    funktionierts denn mit einem node objekt?



  • nein.

    auch nur no match for operator<<.



  • dann kann er wohl typename tree<T>::node nicht herleiten. welchen compiler verwendest du? versuchs einfach mal mit einem anderen



  • ~% g++ --version
    g++ (GCC) 3.3.5 (Debian 1:3.3.5-2)

    Ein anderer Compiler kommt aber nicht in Frage. Soll auf jeden Fall mit dem funktionieren.
    Heißt das, bei dir funktioniert es?
    Wie kann ich das hinbiegen?



  • Das darf doch nicht funktionieren. Bei Template-Argumenten wird zum matchen keine implizite Umwandlung durchgeführt. Die "item ist eine node"-Beziehung bringt dir also gar nichts.

    template<class T>
    ostream& operator<<(ostream& out, const typename tree<T>::item& n) {
        return out << static_cast<tree<T>::node(n);
    }
    


  • hmm die ersetzung von node durch item(bzw umgekehrt) bringt aber auch nichts, wie bereits oben erwähnt



  • Hier das Problem kürzer:

    template <typename T>
    struct Wrap {
       struct Inner {
       };
    };
    
    template<typename T>
    void func(typename Wrap<T>::Inner const & n) {
    }
    
    int main() {
       func( Wrap<int>::Inner() );
    }
    


  • Helium schrieb:

    Das darf doch nicht funktionieren. Bei Template-Argumenten wird zum matchen keine implizite Umwandlung durchgeführt. Die "item ist eine node"-Beziehung bringt dir also gar nichts.

    template<class T>
    ostream& operator<<(ostream& out, const typename tree<T>::item& n) {
        return out << static_cast<tree<T>::node(n);
    }
    

    hmm, bin mir nicht sicher, ob du mein Vorhaben richtig siehst.
    Mein Beispiel nochmal ohne template und verschachtelter Klasse
    (wie es auch gut funktioniert):

    struct Base {
      virtual ostream& write(ostream& out) = 0;
    };
    
    struct Derived : public Base {
      ostream& write(ostream& out) { out<<....; }
    };
    
    ostream& operator<<(ostream& out, Base& b)  {
      return b.write(out);
    }
    
    Base* b = new Derived();
    cout << *b;
    

    Und genau das möchte ich jetzt innerhalb einer Template-Klasse.

    Ponto schrieb:

    Hier das Problem kürzer:[/cpp]

    Ah, danke. Soweit konnte ich das nicht reduzieren.

    Aber auch mit der Kurzfassung kann ich keinen Denkfehler erkennen. 😕



  • Ich denke der Code ist richtig, aber dass die Compiler unfaehig sind, das Template zu finden. Hab es mit icc 8.1 und g++ 4.0.0snapshot getestet.

    Folgendes funktioniert in meinem Testcase, was vielleicht auf das Problem hinweist, dir aber beim operator<< nicht helfen wird:

    template <typename T>
    struct Wrap {
       struct Inner {
       };
    };
    
    template<typename T>
    void func(typename Wrap<T>::Inner const & n) {
    }
    
    int main() {
       func<int>( Wrap<int>::Inner() );
    }
    


  • Ich fand das Problem so interessant, dass ich es mal die Frage in comp.lang.c++ gestellt habe.

    Message-Id: uocp92-42u.ln1@ID-80222.user.uni-berlin.de
    Ansonsten ggg: "template not found" und nach Datum sortieren.



  • Sind schon total viele Antworten da...



  • Könnte mir mal jemand nen Link geben, wo das zu finden ist? Ich meine im Internet müsste es doch sowas wie eine Liste der Fragen und Antworte geben? Oder hab ich da was falsch verstanden?



  • Der Beitrag befindet sich in den Google-Groups


Anmelden zum Antworten