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
Foodeclaration - foo.cc: Provide template class
Foodefinition + explicit instantiation ofFoo<int> - bar.cc: Provide
mainfunction usingFoo<Foo_TYPE>whereFOO_TYPEis a macro withintas 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