Continued form C++ shared library & templates
Here we’ll look at how template functions become linked together when a shared library & header expose a template function to use.
We will create a library liba.so from the file a.cpp. The header exposed by the shared library is a.h. Let’s look at the contents of the files:
a.h:
template<typename T>
T f() {}a.cpp:
#include "a.h"
template void f<void>();
void foo() { f<void>(); }The (relevant) symbols present in liba.so are:
0000000000001100 W void f<void>()
00000000000010f0 T foo()
Note that “W” indicates a Weak Symbol.
The user of the shared library is b.cpp:
#include "a.h"
int main() {
f<void>();
}And the relevant symbols in the final binary (with the shared library linked) are:
0000000000001129 W void f<void>()
Observe that even though our liba.so has explicitly instantiated f<void>, the binary still has the definition of f<void> present.
If we add the following line to b.cpp:
extern template void f<void>();Then the symbol becomes:
U void f<void>()
The extern declaration makes the type of the symbol as Undefined, means it will be provided through somewhere else. If there is no explicit instantiation of f<void> in liba.so, there will be no defined symbol available and linking will fail. Also see C++ extern - Explicit template instantiation