3 Stimmen

Verknüpfung von Vorlagen mit g++

Ich implementiere eine Hash-Tabelle und verknüpfte Liste in C++ (keine STL - fragen Sie nicht) unter Verwendung von Vorlagen, und ich bin in Probleme, die Verknüpfung von ihnen mit G++. Wenn ich #include alle meine .cpp-Dateien zusammen, alles funktioniert, so dass mein Code definitiv funktioniert, es ist nur die Verknüpfung, die mich stolpern oben ist.

Ich lese der Abschnitt im GCC-Handbuch über die Instanziierung von Vorlagen aber ich war nicht sicher, wie ich es anwenden sollte.

Mein Problem: Ich habe eine HashMap<T> y HashEntry<T> für meine Hashtabelle ( <T> ist der Wert - meine Schlüssel sind std::string s). Meine verknüpfte Liste hat LinkedList<T> y Node<T> (donde <T> ist der Wert).

In meiner Rautenkarte habe ich:

template <class T> class HashMap {
    ...
    private:
        LinkedList< HashEntry<T> >** buckets;
 }

Dadurch erhalte ich eine verknüpfte Liste von HashEntry<T> s.

In einer separaten Datei habe ich meine Deklaration der Klasse Linked List:

template <class T>
    class Node {
        ...
        private:
             T data;
}

template <class T> class LinkedList {
     ...
     private:
     Node<T> * first;
}

Wenn ich dann versuche, alles zu verknüpfen (nach dem Kompilieren mit g++ -c -frepo *.cpp ), bekomme ich:

g++ -frepo -o app LinkedList.o HashMap.o
[...unrelated errors about not having a main method - they go away when I link that in]
HashMap.o: In function `HashMap<int>::~HashMap()':
HashMap.cpp:(.text._ZN7HashMapIiED1Ev[HashMap<int>::~HashMap()]+0x65): undefined reference to `LinkedList<HashEntry<int> >::~LinkedList()'
HashMap.o: In function `HashMap<int>::insert(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)':
HashMap.cpp:(.text._ZN7HashMapIiE6insertESsi[HashMap<int>::insert(std::basic_string<char,     std::char_traits<char>, std::allocator<char> >, int)]+0xff): undefined reference to     `Node<HashEntry<int> >::setData(HashEntry<int>)'

Beim Herumgoogeln habe ich Vorschläge für die Deklaration der expliziten Vorlagentypen gesehen, die mein Programm verwendet. Dies funktioniert für die HashMap y HashEntry (Ich fügte hinzu ( template class HashMap< int > y template class HashEntry< int > .

Ich kann jedoch nicht herausfinden, wie ich das für LinkedList y Node Klassen, da die Template-Instanzen von HashEntries<int> . ABER, ich kann das nicht in die LinkedList.h Datei, da es sich um #include d durch meine Hash-Tabellen. Ich konnte auch nicht bekommen, eine erweiterte/externe Erklärung arbeiten für sie.

Ich bin sicher, dass ich etwas ganz Einfaches übersehe, damit das alles funktioniert. Irgendwelche Tipps?

4voto

Johan Kotlinski Punkte 24241

Wenn Sie Vorlagenklassen erstellen, ist es keine gute Idee, diese in .cpp-Dateien zu speichern und separat zu kompilieren. Der richtige Weg ist, sie in .h-Dateien zu speichern (sowohl Deklaration als auch Definition) und sie dort einzubinden, wo Sie sie benötigen.

Der Grund dafür ist, dass Vorlagen nur dann kompiliert werden, wenn ihre Vorlagenargumente definiert sind.

(Ich vermeide absichtlich die Erwähnung der export Stichwort).

2voto

robert Punkte 31314

Es sieht so aus, als ob Sie die Mitglieder der Vorlagenklasse in LinkedList.cpp definieren. Templates müssen im Allgemeinen vollständig in der .h-Datei definiert (und nicht nur deklariert) werden. Wie Sie dies umgehen können, finden Sie unter Speicherung von C++-Vorlagenfunktionen in einer .cpp-Datei. Aber ich würde es vermeiden - es verursacht mehr Probleme, als es wert ist.

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