problem understanding templates in c++
Template code is not compiled until the template function is used. But where does it save the compiled code, is it saved in the object file from which used the template function in the first pl开发者_StackOverflow中文版ace?
For example, main.cpp is calling a template function from the file test.h, the compiler generates an object file main.o, Is the template function inside the main.o file? because template code is not inlined, is it?
It's totally compiler implementation dependant. Most compilers will generate code around, inline or in cpp-like files and then compile with that. Sometimes, with optimization setup, some compilers will even reuse the same code instead of recreate it for each cpp.
So you have to see your compiler's doc for more details.
Yes, the template function code is emitted in the main.o
file. Some of it may be inlined, as any other code may be inlined, but in general, code for templates is emitted in any file in which the template is instantiated. Think of it as first instantiating the template code to produce normal non-template functions, and then compiling those functions with whatever inlining and optimization the compiler applies to any other function.
When the same template instantiation (e.g. std::vector<int>
) occurs in multiple compilation units (.cpp
files), there is a bit of difficulty, because the code is instantiated in each of them. There are various ways of handling this, sometimes involving a cleanup step in the linking phase where duplicate template instantiations are resolved into a single one; your compiler manual can provide more information on exactly how it handles that situation.
Template code is compiled even if it is never instantiated. Otherwise, compilers couldn't be required to emit a diagnostic for this:
template< typename T >
void f()
{
blah
}
Template compilation happens in two phases. Besides the basic checks, everything that depends on template parameters can only be checked when a template is instantiated and the formal parameters are filled in with actual types. For example, here
template< typename T >
void f()
{
typename T::nested_type x;
}
T::nested_type
can only be checked after the template is instantiated and an actual type is given for T
. However, a basic check ("given T::nested_type
is a type, is this a valid variable definition?") is performed the moment the compiler encounters the template's definition. (That's why that typename
is required, BTW. Depending on T
, T::nested_type
might just as well be the name of member of T
or a static data member - which would make T::nested_type x;
a syntax error. So we have to tell the compiler to treat T::nested_type
as the name of a type.)
You mean instantiated, not compiled. At compile time the compiler finds out each and every version that your code uses and instatiates (in object files) all the required versions.
It is always inlined (meaning, it is always internal linkage, having inline semantics). It may in fact be not inlined after all, just as an inline function, however, template is not code. It is a "template for making code". Therefore, it will normally reside in a header, except special cases, see below.
There was an idea to make something else, codenamed "export keyword". It was removed from standard.
Special cases: you can compile template instantiations into an object file, without having them used. This is the only way to avoid having all template code inlined. This is how it is done:
template class std::vector<MyClass>;
This will force the compiler to instantiate a template in the current location. C++0x will have a syntax to force compiler not to do it, and have the linker search for template instantiation elsewhere:
extern template class std::vector<MyClass>; // C++0x only
精彩评论