0

While I was programming a linked list as homework, everything was fine until I tried to implement the last method, the one to count the number of elements. After writing it and compiling, every method of the linked list class I was using was now complaining about undefined reference.

So I undone everything until just before creating the count method, and it compiled fine. "I will think about it later", I told myself, "let me just eat a slice of pizza.". Oh, how wrong was I. After I came back, I tried to recompile just to be sure and, for my fear, I got the same error of undefined reference to LinkedList<type>::anything() for every method! Without changing a character of code!

This is the code, throwing a ton of the same error: check on Github (the main is on Trabalho05.cpp and it's in portuguese, but list-related things aren't). I get the following errors:

$ g++ Trabalho05.cpp LinkedList.cpp Lancamento.cpp Node.cpp 
/tmp/cc2rL0ax.o: In function `listarTran()':
Trabalho05.cpp:(.text+0x14): undefined reference to `LinkedList<Lancamento>::empty()'
Trabalho05.cpp:(.text+0x3d): undefined reference to `LinkedList<Lancamento>::begin()'
Trabalho05.cpp:(.text+0x4f): undefined reference to `LinkedList<Lancamento>::iterator::operator->()'
Trabalho05.cpp:(.text+0x6c): undefined reference to `LinkedList<Lancamento>::iterator::operator->()'
Trabalho05.cpp:(.text+0xa4): undefined reference to `LinkedList<Lancamento>::iterator::operator++()'
Trabalho05.cpp:(.text+0xb3): undefined reference to `LinkedList<Lancamento>::end()'
Trabalho05.cpp:(.text+0xca): undefined reference to `LinkedList<Lancamento>::iterator::operator!=(LinkedList<Lancamento>::iterator const&)'
/tmp/cc2rL0ax.o: In function `remTran()':
Trabalho05.cpp:(.text+0x198): undefined reference to `LinkedList<Lancamento>::destroy()'
Trabalho05.cpp:(.text+0x24c): undefined reference to `LinkedList<Lancamento>::remove(unsigned int)'
Trabalho05.cpp:(.text+0x320): undefined reference to `LinkedList<Lancamento>::count()'
/tmp/cc2rL0ax.o: In function `lancarTran()':
Trabalho05.cpp:(.text+0x531): undefined reference to `LinkedList<Lancamento>::push(Lancamento const&)'
/tmp/cc2rL0ax.o: In function `mostraSaldo()':
Trabalho05.cpp:(.text+0x62e): undefined reference to `LinkedList<Lancamento>::begin()'
Trabalho05.cpp:(.text+0x640): undefined reference to `LinkedList<Lancamento>::iterator::operator->()'
Trabalho05.cpp:(.text+0x662): undefined reference to `LinkedList<Lancamento>::iterator::operator++()'
Trabalho05.cpp:(.text+0x66c): undefined reference to `LinkedList<Lancamento>::end()'
Trabalho05.cpp:(.text+0x683): undefined reference to `LinkedList<Lancamento>::iterator::operator!=(LinkedList<Lancamento>::iterator const&)'
Trabalho05.cpp:(.text+0x691): undefined reference to `LinkedList<Lancamento>::begin()'
Trabalho05.cpp:(.text+0x6a3): undefined reference to `LinkedList<Lancamento>::iterator::operator->()'
Trabalho05.cpp:(.text+0x6c5): undefined reference to `LinkedList<Lancamento>::iterator::operator++()'
Trabalho05.cpp:(.text+0x6cf): undefined reference to `LinkedList<Lancamento>::end()'
Trabalho05.cpp:(.text+0x6e6): undefined reference to `LinkedList<Lancamento>::iterator::operator!=(LinkedList<Lancamento>::iterator const&)'
/tmp/cc2rL0ax.o: In function `__static_initialization_and_destruction_0(int, int)':
Trabalho05.cpp:(.text+0x90e): undefined reference to `LinkedList<Lancamento>::LinkedList()'
Trabalho05.cpp:(.text+0x91d): undefined reference to `LinkedList<Lancamento>::~LinkedList()'
Trabalho05.cpp:(.text+0x92c): undefined reference to `LinkedList<Lancamento>::LinkedList()'
Trabalho05.cpp:(.text+0x93b): undefined reference to `LinkedList<Lancamento>::~LinkedList()'
collect2: error: ld returned 1 exit status

I have never had this same issue before, and after thorougly searching, I did not found similar problems of an entire class being undefined referenced.

ranieri
  • 2,030
  • 2
  • 21
  • 39
  • You probably defined function templates in your .cpp file. You have to move them to your header file, the entirety of a template must be visible at its point of instantiation. – M.M Apr 22 '14 at 03:25
  • I think typically you need to include the template source in the file where it is being used. Not sure what g++ does when you compile all files at the same time, but it's probably the same. (like @ranisalt just said, too ;-) ). – Peter - Reinstate Monica Apr 22 '14 at 03:26
  • Whatever it is, it's most likely in http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix – chris Apr 22 '14 at 03:26
  • possible duplicate of [Why can templates only be implemented in the header file?](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – n. m. could be an AI Apr 22 '14 at 07:01

1 Answers1

1

The issue is that it's trying to instantiate the template with the type Lancamento and it can't find the code in LinkedList.cpp. At some stage the compiler needs all of the following in the same file (technically: same translation unit):

  • the definition of Lancamento
  • the full definition of LinkedList (including methods)
  • a reference to LinkedList<Lancamento>

Where is up to you. When using templates it's best to put all the template code in a header together, using inline if need be on methods. Check here for further reading.

Also, I strongly recommend to use std::list. The standard library is your friend and will do things better than you can.

Cramer
  • 1,785
  • 1
  • 12
  • 20
  • You mean I should put the codes insite the `.h` file (maybe make it `.hpp`) instead a separate header and source file? I was also thinking about separating the `ListaContabil` to a class with a `LinkedList` as an attribute, would this approach work? – ranieri Apr 22 '14 at 04:28
  • @ranisalt C++ will automatically instantiate any needed template for which it can see a definition, if it can't see one it'll just leave a reference as you see here. If you want to supply the definition separately for a given set of args you can e.g. `template class LinkedList;` in some source file where the definitions of both are visible, that's "explicit instantiation". – jthill Apr 22 '14 at 05:20
  • @ranisalt, please read the link provided in the answer, it will explain what is wrong, I've also clarified a bit in the answer. – Cramer Apr 22 '14 at 06:12