Связывание шаблонов с g ++ - PullRequest
3 голосов
/ 22 декабря 2010

Я реализую хеш-таблицу и связанный список в C ++ (без STL - не спрашивайте) с использованием шаблонов, и я сталкиваюсь с проблемами, связывающими их с g ++.Если я #include все мои файлы .cpp вместе, все работает, так что мой код определенно работает, это просто ссылка, которая сбивает меня с толку.

Я прочитал бит в руководстве GCC о создании шаблона , но не знал, как его применить.

Моя проблема: у меня есть HashMap<T> и HashEntry<T> для моей хэш-таблицы (<T> - это значение - мои ключи std::stringс).В моем связанном списке есть LinkedList<T> и Node<T> (где <T> - это значение).

В моей хэш-карте у меня есть:

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

, которая дает мне связанный списокHashEntry<T> с.

В отдельном файле у меня есть объявление класса Linked List:

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

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

Затем, когда я пытаюсь связать все (после компиляции с g++ -c -frepo *.cpp), я получаю:

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>)'

Погуглив, я видел предложения по объявлению явных типов шаблонов, которые использует моя программа.Это работает для HashMap и HashEntry (я добавил (template class HashMap< int > и template class HashEntry< int >.

Однако я не могу понять, как заставить это работать для LinkedList и Nodeклассы, так как экземпляры шаблона имеют HashEntries<int>. НО, я не могу поместить это в файл LinkedList.h, так как это по моим хэш-таблицам #include d. Я также не смог заставить работать расширенную / внешнюю декларациюдля этого.

Я уверен, что есть кое-что довольно простое, что мне не хватает, чтобы заставить все это работать. Любые советы?

Ответы [ 2 ]

3 голосов
/ 22 декабря 2010

Если вы создаете шаблонные классы, не рекомендуется помещать их в файлы .cpp и компилировать отдельно. Правильный способ - поместить их в файлы .h (как декларации, так и определения) и включать их там, где они вам нужны.

Причина в том, что шаблоны на самом деле не будут компилироваться, если не определены их аргументы шаблона.

(Намеренно избегать упоминания ключевого слова export.)

2 голосов
/ 22 декабря 2010

Похоже, вы определяете членов класса шаблона в LinkedList.cpp.Шаблоны, как правило, должны быть полностью определены (а не только объявлены) в файле .h.Чтобы обойти это, см. хранение шаблонных функций C ++ в файле .cpp. Но я бы избежал этого - это вызывает больше проблем, чем стоит.

...