简体   繁体   English

问题理解c ++中的模板

[英]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 place? 但它在哪里保存已编译的代码,它是否保存在首先使用模板函数的目标文件中?

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? 例如,main.cpp从文件test.h调用模板函数,编译器生成一个目标文件main.o,是main.o文件中的模板函数吗? 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. 大多数编译器将生成代码,内联或类似cpp的文件,然后使用它进行编译。 Sometimes, with optimization setup, some compilers will even reuse the same code instead of recreate it for each cpp. 有时,通过优化设置,一些编译器甚至可以重用相同的代码,而不是为每个cpp重新创建它。

So you have to see your compiler's doc for more details. 因此,您必须查看编译器的doc以获取更多详细信息。

Yes, the template function code is emitted in the main.o file. 是的,模板功能代码在main.o文件中发出。 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 (eg 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. 当在多个编译单元( .cpp文件)中发生相同的模板实例化(例如std::vector<int> )时,存在一些困难,因为代码在每个中都被实例化。 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 . 只能在实例化模板后检查T::nested_type并为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. 但是,在编译器遇到模板定义的那一刻,执行基本检查(“给定T::nested_type是一种类型,这是一个有效的变量定义吗?”)。 (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.) (这就是为什么需要typename ,BTW。根据TT::nested_type也可能是T的成员名称或静态数据成员 - 这将使T::nested_type x;语法错误。所以我们必须告诉编译器将T::nested_type视为类型的名称。)

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". 有一个想法是制作别的东西,代号为“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: C ++ 0x将具有强制编译器执行此操作的语法,并让链接器在其他位置搜索模板实例化:

extern template class std::vector<MyClass>; // C++0x only

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. 在编译时,编译器会找出代码使用的每个版本,并在目标文件中实例化所有必需的版本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM