请注意,代码仅针对被调用的成员函数进行实例化.对于类模板,只有在使用成员函数时才会对其进行实例化.
以上引用来自Addison Wesley的书:C++模板.
我想理解术语" 代码被实例化 " 的含义.这是否意味着只保留特定内存,或只编译该代码或其他内容?
这是一个非常有趣的问题,应该在编译器处理模板的更广泛的上下文中完成.基本上模板是编译器生成函数类的代码模式.模板可用于生成从无代码(如果从未使用过)到无限数量的实例化的任何内容.
模板不能直接编译成任何后来与不同参数一起使用的实体(在C#泛型中都是如此,但不是C++),而是由编译器解析代码并在内存中保存,以防以后使用处理当前的翻译单位.也就是说,编译器处理模板(斜体模板用于创建事物的模式的英语形式,而不是精确的C++含义),在需要时它将从中创建代码(类或函数).实例化是由编译器确定特定的模板的过程中使用具有一组特定的参数,并且执行参数替换对模板来生成类或函数来编译和最后汇编到模板的二进制代码.
有两种类型的模板实例化,隐式和显式,您引用的引用是关于隐式模板实例化.我将从显式模板实例化开始,因为它更简单.当您显式实例化模板(google的语法)时,您告诉编译器您希望从该模板生成的代码应用于您提供的特定参数.在类模板的情况下,它强制实例化所有成员函数,这基本上意味着编译器将替换类型并将其结果编译为二进制对象.
另一方面,隐式实例化是按需执行的.使用类模板时,实际使用的位和部分将从模板生成并编译到转换单元中.如果您创建了一个变量定义std::vector<int> v;,编译器会将类型int(和默认类型std::allocator<int>)应用于template std::vector并创建一个类型std::vector<int>,但这样做时,它不会编译所有成员函数,而只会编译所需的那些,在这种情况下它将是默认构造函数 std::vector<int>::vector()和析构函数std::vector<int>::~vector().其余的方法没有编译,二进制文件中没有代码.
没有实例化所有成员函数的原因有几个,原因在于从简单到深入的语言细节的复杂性.对于一些较简单的,你可以考虑编译的性能(不必生成/编译所有成员函数只是因为使用其中一个将减少编译时间相当多).稍微复杂的是,模板中的不同成员函数可能对实例化类型施加不同的要求.例如,operator[]在map要求值的类型是默认constructible,作为运营商将创建一个新的元素,如果它没有在地图上已经存在,而另一方面,如果你总是使用find和insert,您可以使用std::map与不是默认构造的类型.通过不强制编译所有成员函数,该语言允许您使用具有不满足所有方法的所有要求的参数的模板,只要它确实满足实际使用的那些方法的要求即可.
我在上面的描述中使用了相当多的术语,但我还没有定义它.对于一个精确的定义,你将不得不去的标准,但可以作为一个很好的近似认为这是一个成员函数使用,如果它被称为从你的代码直接或间接(即你怎么称呼它,或其他一些成员函数,你实例化调用它)或者如果你获得成员函数的地址.
| 归档时间: |
|
| 查看次数: |
3222 次 |
| 最近记录: |