typedef Problem



  • Das is der Code:

    #include <hash_map>
    
    using namespace std;
    using namespace __gnu_cxx;
    
    template <typename vertex_type>
    class Graph
    {
    	typedef pair<vertex_type,vertex_type>	vertex_type_pair;
    	typedef hash_multimap<vertex_type,vertex_type>	C1;
    	//... Klammer zu usw.
    

    ,

    das sagt der Compiler:

    type \_\_gnu\_cxx::hash\_multimap<vertex\_type, vertex\_type, \_\_gnu\_cxx::hash<\_Key>, std::equal\_to<\_Key>, std::allocator<\_CharT> >' is not derived from typeGraph<vertex_type>'

    (bezieht sich auf die vorletzte Zeile im Code).

    Was mache ich falsch? Das erste typedef scheint doch auch zu funktionieren. Ich bin soweit gekommen, das es wohl einen Unterschied zwischen 'typedef' und 'typedef typename' gibt, aber ich kann das nicht so richtig nachvollziehen. Wann reicht typedef, wann brauch ich beide?



  • Du brauchst typedef typename, wenn du einen abhängigen Typnamen hast (dependant name). pair<T, T> ist so ein Fall - der Name ist noch unvollständig. Hier verlangt der Standard, so einen abhängigen Namen mit typename zu qualifizieren.



  • Da du vertex_type wohl noch häufiger benutzt und es oft praktisch ist, von einer Template Klasse ihren Typ zu erfahren, könntest du sowas machen:

    template <typename vertex_t>
    class Graph
    {
    public:
        typedef typename vertex_t vertex_type;
    // Rest wie bisher
    

    Spart viel Arbeit 😉


  • Mod

    vertex_type ist bereits in der deklaration als typ qualifiziert worden, ein weiteres typename in der definition ist nicht notwendig (und daher falsch)(dass ein typedef darauf trotzdem - aus anderen gründen - sinn machen kann, soll hier ausser acht bleiben).

    pair<T,T> ist immer ein typ, völlig unabhängig von T, benötigt also kein typename (und darf es daher auch nicht bekommen). typename benötigt grundsätzlich eine qualifizierte id, also etwas der form X::id (ausser in template deklarationen versteht sich)

    I glaube nicht, dass die gezeigten zeilen allein das problem sind - darauf deutet auch die fehlermeldung hin.



  • Hmm.. danke für die Hilfe.

    Diese typedef Orgien sind für mich Neuland, aber sie scheinen ja gang und gäbe zu sein; offensichtlich kommt man bei intensiverem STL / template Gebrauch auch nicht drumherum, wenn man seinen Code lesbar halten will.

    Der gezeigte Codeausschnitt ist während des Korrekturprozesses entstanden, Auslöser war eher:

    typedef /*typename <-ohne das*/ hash_multimap<vertex_type,vertex_type>::const_iterator	const_iterator;
    

    oder sowas. Die korrigierte Version läuft anstandslos durch.

    @7H3 N4C3R, ich schätze du meinst sowas mit "dependant name"? Der pair typedef macht nämlich keine Probleme.

    @.filmor, 😉 gemeint? Ich seh den Sinn nämlich nicht, 3 Zeichen mehr als vorher.. oder gibts noch anderen Nutzen?

    @camper: kann ich also den Umkehrschluss verinnerlichen, also typedef X::id benötigt typename (bzw. das klingt nach der Aussage von 7H3 N4C3R: X::id dependant name, ergo typename benötigt)?



  • Das mit dem typename war Quatsch, wie camper schon sagte. Dennoch kann es oft praktisch sein, den Template-Typ der "Außenwelt" bekannt zu machen (wenn du beispielsweise einen Vertex für einen bestimmten Graphen erstellen musst, von diesem aber nicht den vertex_type weißt (z.B. in einer Template-Funktion/-Methode).


  • Mod

    O_o schrieb:

    typedef /*typename <-ohne das*/ hash_multimap<vertex_type,vertex_type>::const_iterator	const_iterator;
    

    hier muss es zwingend hin. ohne einen konkreten typ zu haben, um hash_multimap zu instantiieren, kann der compiler nicht wissen, was const_iterator ist. Selbst wenn er das template schon gesehen hat, in dem const_iterator ein typ ist, könnte ja noch eine spezialisierung folgen, in der es ein objekt oder template bezeichnet, oder gar nicht existiert.

    @camper: kann ich also den Umkehrschluss verinnerlichen, also typedef X::id benötigt typename (bzw. das klingt nach der Aussage von 7H3 N4C3R: X::id dependant name, ergo typename benötigt)?

    wenn X von den template parametern abhängt (direkt oder indirekt - aber nur dann), dann benötgst du typename, um X::id als typ verwenden zu können.



  • Alles klar. Danke nochmal :).



  • O_o schrieb:

    @7H3 N4C3R, ich schätze du meinst sowas mit "dependant name"? Der pair typedef macht nämlich keine Probleme.

    Jo, das war gemeint. Das mit dem pair war Käse... in anbetracht der Uhrzeit möge man mir vergeben 😃


Log in to reply