This gist highlights the fact that implementation of C++ template symbols do not necessary have to be available where there are used.
- foo.hh: Provide template class
Foo
declaration - foo.cc: Provide template class
Foo
definition + explicit instantiation ofFoo<int>
- bar.cc: Provide
main
function usingFoo<Foo_TYPE>
whereFOO_TYPE
is a macro withint
as default value.
Run make
to successfully build the main
executable despite compiler does not know implementation of Foo::incr
when compiling bar.cc
$ make
g++ -Wall -ansi -pedantic -Werror -c -o foo.o foo.cc
g++ -Wall -ansi -pedantic -Werror -c -o bar.o bar.cc
g++ foo.o bar.o -o main
Run CPPFLAGS="-DFOO_TYPE=double" make distclean all
to see that bar.cc
compilation passes but linkage doesn't.
$ CPPFLAGS="-DFOO_TYPE=double" make distclean all
rm -f foo.o bar.o
rm -f main
g++ -Wall -ansi -pedantic -Werror -DFOO_TYPE=double -c -o foo.o foo.cc
g++ -Wall -ansi -pedantic -Werror -DFOO_TYPE=double -c -o bar.o bar.cc
g++ foo.o bar.o -o main
bar.o: In function `main':
bar.cc:(.text+0x33): undefined reference to `Foo<double>::incr(double const&)'
collect2: error: ld returned 1 exit status
Makefile:7: recipe for target 'main' failed
make: *** [main] Error 1