Christof Warlich wrote:
> Rolf Magnus wrote:
>
> > No. There could be another translation unit that defines doSomething() and
> > also instantiates the template for int. Then there would be an
> > implementation, but only the linker could find it.
>
> I was hoping to get exactly this answer
as it makes sense and could
> solve my design issue (see my post "virtual constructor ideom with
> templates" above). But it unfortunately did not work: I tried the
> following code, trying to translate it with
>
> $ g++ -c main.cc
> $ g++ -c implementation.cc
> $ g++ main.o implementation.o -o main
>
> but I still get the same error message from the linker. Any idea how
> this can be made work?
>
> Thanks,
>
> Christof
>
> // template.h
> template<typename T> class X {
> public:
> void doSomething(T t);
> };
> // template.h ends
>
> // main.cc
> #include "template.h"
> int main(void) {
> X<int> x;
> x.doSomething(4);
> return 0;
> }
> // main.cc ends
>
> // implementation.cc
> #include "template.h"
> template<typename T> void X<T>::doSomething(T t) {
> // do something useful
> }
> X<int> dummy;
> // implementation.cc ends
The definition of a template must be visible at the point it is needed
in a source file. In this case, the doSomething() method is needed in
main.cc, but its definition is not visible to main.cc. Instead
doSomething's definition is found in implementation.cc - a source file
which has no need for it.
In order to ensure that template definitions are available to the
source code files that need them, the easiest solution (at least in the
absence of template export support) is to place template definitions in
header files. Therefore moving doSomething()'s definition to, say,
template.h while having main.cc include template.h would be the most
straightforward way to fix this problem.
Greg