7

I am trying to use a template class and when I compile it in one file in LWS it works:

(Link is dead) ~http://liveworkspace.org/code/a9c412a7e683439dfa35a9363749369d~

But when I try to compile it made-up of 3 files,

stack.h lines 4 to 21

stack.cpp lines 24 to 48

main.cpp lines 49 to end

When I try to compile those 3 files I get

Undefined symbols for architecture x86_64:
  "Stack2<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::push(Node**, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)", referenced from:
      _main in ccCoizCT.o
  "Stack2<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::top(Node*&)", referenced from:
      _main in ccCoizCT.o
  "Stack2<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::pop(Node*&)", referenced from:
      _main in ccCoizCT.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

Yes I have included stack.h in a stack.cpp and main.cpp files

The Matt
  • 1,423
  • 1
  • 12
  • 22
Jack F
  • 543
  • 4
  • 12
  • 24
  • 2
    Your template function bodies need to ALL be in your header files. If you trimmed these using the lines you mentioned, you have template<> bodies in .cpp files, they must be available for the compiler to perform deduction, and thus must be in the header file. – WhozCraig Oct 15 '12 at 23:26
  • so which lines should i insert to the header file? – Jack F Oct 15 '12 at 23:27
  • 1
    Judging by your code, you shouldn't even *need* a stack.cpp file, if that helps. Move all Stack template implementations to your header. – WhozCraig Oct 15 '12 at 23:27
  • btw, your pop function is leaking memory. – WhozCraig Oct 15 '12 at 23:32
  • yes it works now, but is there a way that I could keep the stack.cpp file? – Jack F Oct 15 '12 at 23:32
  • not if you're implementing this as a template. think of how templates work. the compiler, based on the *usage* of template code, will deduce what needs to be generated for you. To do this, the templates must be available in the compile-phase of the current source module (cpp file in your case). You have it right if they're in the header now. So go fix your memory leak =P – WhozCraig Oct 15 '12 at 23:34
  • And sashang has the correct answer (see below), so you may want to review that, especially the link he provided, and mark his answer after reading it. – WhozCraig Oct 15 '12 at 23:38

1 Answers1

15

Sounds like you need to place the template definitions of stack back in the header file. Templates form a plan for code generation, so if the compiler can't see the entire template definition and only sees the declaration, code for that specific instantiations of the template will not be generated. It will simply trust the declaration and expect that at link time there exists an objects file with the instantiations of those templates. The solution to this is 1) keep the template definitions in the header file or 2) pre-generate the required definitions so the linker can find them at link time.

See here: Template issue causes linker error (C++)

sashang
  • 11,704
  • 6
  • 44
  • 58
  • It should be worth noting that after moving the implementation back to the header file, if the error persists, to `make clean` and `make` again afterwards to refresh the object files. – gmdev Aug 14 '21 at 12:51