16

Possible Duplicate:
Why can templates only be implemented in the header file?

I've been trying around with C++ recently. At the moment I'm trying to program something I'm sure everone has done at least once: A simple LinkedList class. The code is done, but I'm somehow failing to compile it. I've been googling and it seems like I'm linking the object files wrong. That's what my code basically looks like:

test.cpp

#include "linkedlist.h"

int main()
{
    LinkedList<int> list;
    // do something
}

linkedlist.h

template <typename T>
class LinkedList
{
   // a lot of function and variable definitions
}

Then there's a .cpp file called linkedlist.cpp which contains all the actual code of the LinkerList class. When trying to compile test.cpp using the following command:

g++ ..\src\test.cpp

I'm getting told that there's an undefined reference to 'LinkedList::LinkedList()'. So I've been thinking that it's being linked wrong as there's more than one .cpp file, so I tried it like this:

g++ -c -Wall -O2 ..\src\test.cpp
g++ -c -Wall -O2 ..\src\linkedlist.cpp
g++ -s test.o linkedlist.o

However, this doesn't change anything. The error messages stay the same. I've been trying to find some information on the internet, however, it didn't really work out.

Community
  • 1
  • 1
haiyyu
  • 2,194
  • 6
  • 22
  • 34
  • 3
    Well done for formulating this completely and coherently. :) Rare for a newcomer, nowadays :( – Lightness Races in Orbit Jan 12 '12 at 14:43
  • Since the `LinkedList` is a template class, users of that class needs the full definition of all methods. One way of doing it is having all methods inline in the class, while another is to put the methods in a separate file and include them in the header file. – Some programmer dude Jan 12 '12 at 14:45
  • @Mike: It's hard to call that a "duplicate" per se. This is where things get fuzzy -- the question is completely different, even though we don't need to cover the same ground again. :) – Lightness Races in Orbit Jan 12 '12 at 14:46
  • @MikeSeymour: Slippery slope, that. Plenty of answers on SO may be good for totally unrelated questions! I'm just being difficult, though. – Lightness Races in Orbit Jan 12 '12 at 14:49
  • As I said, I was looking for answers for a while before deciding to ask it on here. Although it covers the same problem, I had no idea that this might be the reason. Probably because I used VS10 before g++, and it worked just fine there. – haiyyu Jan 12 '12 at 14:54
  • Hmm, it shouldn't work in Visual Studio, either. Also, [this](http://stackoverflow.com/questions/456713/why-do-i-get-unresolved-external-symbol-errors-when-using-templates) looks like a better duplicate that actually includes a description of the problem encountered here. – Cody Gray - on strike Jan 12 '12 at 14:57
  • Yea I guess the "fuzziness" I was talking about can be characterised as the fact that this is not a _punitive_ dup-close; you couldn't have been expected to know that that question was about the same issue. It's more of a "here's your answer: this is the topic you're looking for, found elsewhere" dup-close. – Lightness Races in Orbit Jan 12 '12 at 23:18

5 Answers5

6

You're creating a class template, which has the important caveat that all variable definitions must be placed in the header file so that they're accessible to all translation units during compilation.

The reason is the way that templates work. During compilation, the compiler instantiates template classes based on your class template definition. It isn't enough for it to have access to only the declarations or signatures: it needs to have the entire definition available.

Move all of your method definitions out of the .cpp file and into the .h file, and everything should be fine (assuming that you have, in fact, provided a definition for the default constructor!).

Alternatively, you might be able to get around this by explicitly telling your compiler to instantiate the appropriate template class using something like template class LinkedList<int>, but this really isn't necessary in such a simple case. The primary advantage of this over including all of the definitions in the header file is that it potentially reduces code bloat and speeds up compilation. But it might not be necessary at all, as compilers have gotten a lot smarter at applying appropriate optimizations.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
2

You have split up your class LinkedList and put the declaration in a header and the defintion in a source-file. This does not work for a template. Both have to be in the header.

Community
  • 1
  • 1
Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
1

Since LinkedList is a class template, the definitions of its member functions ought to go in a header.

(They don't have to be, strictly speaking, but this is the easiest way to get around the complexities of template instantiation without going totally off-piste with inclusion conventions.)

Oh, and you'd need to take your second build approach anyway; you should link together all .cpp files, or use the -c switch to compile one at a time then link the results together later.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
1

Template class is like a definition of a rule by which to construct an actual class. The actual classes are created (instantiated) by the compiler wherever there is instantiation of template class. For this reason all the code of template class must be visible to a compiler at that point, and that's why you have to write all the template functions and methods in a header files - because you only include headers to cpp files, only headers are visible to a compiler at that point. You don't include cpp files to another cpp files, and you should never do that.

Correct me if my understanding is wrong.

P. S. Does C++11 address this issue?

Violet Giraffe
  • 32,368
  • 48
  • 194
  • 335
0

there's an undefined reference to 'LinkedList::LinkedList()'

Have you checked to see if your LinkedList class has a constructor?

ChrisBD
  • 9,104
  • 3
  • 22
  • 35