0

I was starting to code a library, and decided to do a test, but I'm getting the error in the question title (Mac OSX, gcc-4.7.1):

tlib.cpp:

template <typename T>
T dobra(const T& valor){
  return valor*2;
}

tlib.h:

template <typename T>
T dobra(const T& valor);

test2.cpp:

#include "tlib.h"
#include <iostream>

using namespace std;

int main (int argc, char const *argv[])
{ 
  double b = dobra<double>(10);
  cout << b << endl;
  return 0;
}

Compiling:

no25-89:CPROP canesin$ g++ -dynamiclib -Wall -std=c++11 tlib.cpp -o libdobra.so
no25-89:CPROP canesin$ g++ test2.cpp -Wall -std=c++11 -o test2 -L. -ldobra
Undefined symbols for architecture x86_64:
  "double dobra<double>(double const&)", referenced from:
      _main in cctLJGqf.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
no25-89:CPROP canesin$ 
canesin
  • 1,967
  • 2
  • 18
  • 30
  • 1
    possible duplicate of [Why do I get "unresolved external symbol" errors when using templates?](http://stackoverflow.com/questions/456713/why-do-i-get-unresolved-external-symbol-errors-when-using-templates) – Bo Persson Jun 23 '12 at 02:06

1 Answers1

2

A fact of life in C++ is that you must include a complete implementation of a template in every compilation unit it's used in, or restrict yourself to specific instantitions.

In practice, this means that you either:

  1. Put what you've got in tlib.cpp into tlib.h. This is the most common solution.
  2. Restrict yourself to only ever using (say) dobra<double>, and put an explicit instantiation into tlib.cpp:

    template double dobra<double>(const double& valor);

Managu
  • 8,849
  • 2
  • 30
  • 36
  • OP is using a pretty new gcc - I seem to remember so compiler switches that helped with templates - trying to find them now – Adrian Cornish Jun 23 '12 at 06:30
  • @AdrianCornish: Older would probably be better. GCC at one point supported the, errm, cfront model? Where you could declare templates in one source file and define them in another, and the compiler and linker would work together and just make things work. It either never caught on, or never actually worked well. I think doing this was an optional feature in the C++98 standard. It was never widely implemented, is therefore not at all portable, and pretty much died for C++11. – Managu Jun 23 '12 at 06:33
  • http://gcc.gnu.org/onlinedocs/gcc/Template-Instantiation.html might be a good place to start if you really want to go down that road. – Managu Jun 23 '12 at 06:36
  • Agree template handling is awful in most compilers - but I was think of this option I believe "-frepo Enable automatic template instantiation at link time. This option also implies -fno-implicit-templates." Not sure if would help the OP as you answer 1 is the best way to go I think – Adrian Cornish Jun 23 '12 at 06:40