Reputation: 1101
I am confused about a specific aspect of templates. When I have multiple source files and the same template type, does the source code for the template get compiled multiple times, once for each source file?
Example below test_one.h
#include <vector>
class cars:
{
std::vector<double> speeds;
vector<char> are_speeding(double);
}
test_one.cpp
#include "test_one.h"
std::vector<char> cars::are_speeding(double speed_limit)
{
std::vector<char> ans;
for (int i = 0; i < speeds.size() ; i++)
{
if(speeds[i] > speed_limit)
ans.push_back(1);
else
ans.push_back(0);
}
return ans;
}
test_two.h
#include <vector>
class poodle
{
std::vector<double> odor_strength;
}
So is the vector header source code compiled twice for std::vector or only once?
Upvotes: 0
Views: 219
Reputation: 154025
Independent on whether the header contains a template or not, the respective header files are processed in each translation unit they end up being included. That is, the code is compiled every time it is included.
When a template is being used in a translation unit it is instantiated. I guess, this is the aspect you are actually interested in. That is, you may end up with an instantiation of a template in multiple object files. If you look at the symbols in an object file (e.g. on UNIX system you can use nm -po object.o
; I think on Windows you'd use libtool
but it is a long time since I used Windows), you can normally see some function definitions. When the different object files are combined by the linker duplicate definitions will be thrown out, i.e., they don't cause any semantic problems.
It is worth noting that instantiating templates may take quite a bit of time, especially when optimizations are turned on and the same instantiations are used in many translation units. For example, IOStreams and strings are getting used often and typically it is always the same instantiation (either using wchar_t
or char
). The approach to deal with it as the implementer of a template is to use extern
declaration for templates and explicitly instantiate them in suitable translation units (here is some more detail I wrote on this).
Upvotes: 2
Reputation: 249582
Yes, templates are typically defined in header files and "compiled" (instantiated) separately in each translation unit in which they are used. On many systems this results in the "same" object code being emitted in multiple object files, but the linker will "collapse" them when the final executable is produced.
Unfortunately, this doesn't all cases, for example if you use vector<int>
and vector<unsigned>
those could in principle share the same object code for most functions, but in practice they probably will not. This is one source of instruction cache wastage or "bloat" in C++ relative to C where type erasure is more common when building containers.
Upvotes: 0
Reputation: 2864
Your compiler will compile the template multiple times, but it will only link to it once.
This is the same way inline functions are handled.
Upvotes: 0