I'm trying to move a template function's definition out of the header file.
I know that in order to do this I can explicitly instantiate this function with all the types that I want to see from the outside (during the linkage). However, inside of the source file (together with the function's definition) I have the usage (implicit instantiation) of the function with all the necessary types. This code works and links perfectly with -O0, but fails to link with -O2.
I was able to minimize the problem:
// a.cpp
#include "b.h"
int main() {
bar<int>();
return 0;
}
// b.h
template <class T> void bar();
// b.cpp
#include "b.h"
template <class T> void bar() {}
void foo() { bar<int>(); }
If I compile b.cpp with -O0 and with -O2 I get a different set of symbols available in the object file:
> clang++ -c b.cpp -o b.o && nm -A b.o
b.o:0000000000000000 W _Z3barIiEvv
b.o:0000000000000000 T _Z3foov
> clang++ -c b.cpp -O2 -o b.o && nm -A b.o
b.o:0000000000000000 T _Z3foov
The same happens with gcc as well.
It looks like compilers inline the instantiated function and delete it as they don't see any other usages of it.
Is it possible to keep implictly instantiated template functions from being deleted without explicitly instantiating them?
Thanks in advance!
UPD: this answer for a related question (as pointed out by @Jarod42) answers my question as well: according to the standard it is impossible to do this without an explicit instantiation.