c++compiler-errorsavl-tree

Error "undefined reference to" when I compile a C++ code, but the original makefile code compiles


I downloaded a generic AVL implementation from: http://sourceforge.net/projects/standardavl/files/standardavl/0.1/

The makefile in this project compiles correctly the code. The compiler produces the follow output:

g++ -pedantic -Wall -O3 -c standardavl.cpp -o standardavl.o
g++ -pedantic -Wall -O3 -c Point.cpp -o Point.o
g++ -o standardavl  standardavl.o Point.o
g++ -o genpoints genpoints.o Point.o

The makefile compiles only "standardavl.cpp", because standartavl includes "AvlTree.h" and this file includes "AvlTree.cpp":

standardavl.cpp

#include "AvlTree.h"
#include "Point.h"
(...)

AvlTree.h

(...)
#include "AvlTree.cpp"

In my project I removed the last line (#include "AvlTree.cpp") from the file AvlTree.h and compiled individually that files. I do not use the file "standardavl.cpp" also. I changed the file Point.h to KeyPair.h and implemented all operators there.

My compiler produces the follow output:

g++ -pedantic -Wall -O3 -c -o ../lib/CPUTimer.o ../lib/CPUTimer.cpp -I. -I../lib 
g++ -pedantic -Wall -O3 -c -o ../lib/AvlTree.o ../lib/AvlTree.cpp -I. -I../lib 
g++ -pedantic -Wall -O3 -c -o ../lib/keypair.o ../lib/keypair.cpp -I. -I../lib 
g++ -pedantic -Wall -O3 -c -o graph.o graph.cpp -I. -I../lib 
g++ -pedantic -Wall -O3 -c -o dijkstra.o dijkstra.cpp -I. -I../lib 
g++ -pedantic -Wall -O3 -o ../../q1 ../lib/CPUTimer.o ../lib/AvlTree.o ../lib/keypair.o graph.o dijkstra.o questao1.cpp -I. -I../lib 
dijkstra.o: In function 'Dijkstra::executeAvl(int)':
dijkstra.cpp:(.text+0x25d): undefined reference to 'AvlTree<KeyPair, std::less<KeyPair>, nil<KeyPair> >::AvlTree()'
(... a lot of errors like above ...)
collect2: ld returned 1 exit status
make[1]: ** [q1] Erro 1

What I am doing wrong here?


Solution

  • Assuming AvlTree.h declares a template class AvlTree<>, and AvlTree.cpp defines the implementation:

    You can't define the implementation of template code in a separate translation unit (.cpp) -- it must exist where it is used. That's why they included it in the header. Putting the implementation in a .cpp file to be included was just a design choice to keep the .h file concise.

    (Well, technically you can put the template definition in a separate translation unit, but you must explicitly instantiate it for the template arguments you'll be using. I'm guessing that's not what you want to do.)