Imagine that we have two static libraries built with different implementations of std::vector
. Both of these binaries would have the code for both push_back
and pop_back
(since vector is usually header only). What would the linker do when we tried to use both of these libraries in a project. Would it give an error? Could the linker remove one implementation of each of these methods so that following is possible:
push_back
call from the second library calls push_back
implementation from the first library
pop_back
call from the first library calls pop_back
implementation from the second library
Would it give an error? Depends on how you define "error".
It probably would not give you an error at link-time. But it would certainly corrupt your executable. The linker assumes, when it encounters multiple definitions of a symbol, that they are identical, and so all but one of them can be discarded. If they're not identical, you're violating the One-Definition Rule, which means you're heading into Undefined Behavior-land. Anything might happen. Most likely, you'll see random crashes.
The most common (but not the only) approach that the compilation system takes for templates is for the compiler to greedily instantiate all templates that are used in each translation unit, resulting in multiple instantiations. The linker then silently discards the duplicates.
However, I definitely wouldn't rely on this behaviour tto cope with two different implementations of the same (named) template.
Most likely, one of the two implementations will be chosen for the external calls.
Because there are so many gotchas here I wouldn't try to do this. Here are some problems:
- When an object is created, the place it is called handles how many bytes are allocated. So let's assume the two implementations use different members. If the chosen external functions are the ones that assume the larger size, you could corrupt memory.
- While one of the two implementations will be chosen for the external calls, the compiler may have inlined some of the other methods. For the implementation that loses as link time, its inline calls will still exist in the code and will most likely misbehave.
You will end up calling one or another, depending on linker's mood. A bad situation to be in.