开发者

Linking templates with g++

I'm implementing a hash table and linked list in C++ (no STL - don't ask) using templates, and I'm running into problems linking them with g++. If I #include all my .cpp files together, everything works, so my code definitely works, it's just the linking that's tripping me up.

I read the bit in the GCC manual about template instantiation, but wasn't sure how to apply it.

My problem: I have a HashMap<T> and HashEntry<T> for my hash table (<T> is the value - my keys are std::strings). My linked list has LinkedList<T> and Node<T> (where <T> is the value).

In my hash map, I have:

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

Which gives me a linked list of HashEntry<T>s.

In a separate file, I have my Linked List class declaration:

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

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

Then, when I try to link everything (after compiling with g++ -c -frepo *.cpp), I get:

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 re开发者_开发技巧ference 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>)'

Googling around, I've seen suggestions for declaring the explicit template types that my program uses. This works for the HashMap and HashEntry (I added (template class HashMap< int > and template class HashEntry< int >.

However, I can't figure out how to make this work for LinkedList and Node classes, since the template instances are of HashEntries<int>. BUT, I can't put that into the LinkedList.h file, since it's #included by my Hash tables. I also couldn't get an advanced/extern declaration working for it.

I'm sure there's something fairly simple that I'm missing to make all this work. Any tips?


If you are making template classes, it is not a good idea to put them in .cpp files and compile separately. The right way is to put them in .h files (both declaration and definition) and include them where you need them.

The reason is that templates won't actually be compiled unless their template arguments are defined.

(Intentionally avoiding mentioning the export keyword.)


It looks like you're defining template class members in LinkedList.cpp. Templates generally need to be completely defined (not just declared) in the .h file. For ways around this, see storing C++ template functions in a .cpp file. But I would avoid it--it causes more problems than it's worth.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜