Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板和可执行文件_C++_Templates - Fatal编程技术网

C++ 模板和可执行文件

C++ 模板和可执行文件,c++,templates,C++,Templates,与没有模板的代码相比,编译并链接到PE中的模板代码的大小是否会增加。我认为使用的每个模板实例都是有序打包的,因此如果需要更快的速度,它将输出匹配 很抱歉,我对模板了解不多 C++的工作原理是: 你为你使用的东西付费 模板代码仅为您使用/实例化的代码创建二进制文件 仅仅因为您是根据标准库进行编译的,标准库有数百个STL容器,这并不意味着您的目标代码包含所有STL容器,它只包含您使用的STL容器 模板实现编译时多态性。对于使用不同数据类型执行的每个实例化,都会创建模板化函数的副本,对于模板化类也是如

与没有模板的代码相比,编译并链接到PE中的模板代码的大小是否会增加。我认为使用的每个模板实例都是有序打包的,因此如果需要更快的速度,它将输出匹配


很抱歉,我对模板了解不多

C++的工作原理是:
你为你使用的东西付费
模板代码仅为您使用/实例化的代码创建二进制文件

仅仅因为您是根据标准库进行编译的,标准库有数百个STL容器,这并不意味着您的目标代码包含所有STL容器,它只包含您使用的STL容器


模板实现编译时多态性。对于使用不同数据类型执行的每个实例化,都会创建模板化函数的副本,对于模板化类也是如此。进一步编译此代码以创建二进制文件。因此,二进制文件的大小不会比没有模板的代码产生的大小大。

模板本身根本不占用任何空间。它是该模板的实例化。一旦将模板与类型参数一起使用-
MyClass mc
,它就会被实例化。您使用的每个类型都会创建一个实例化,因此
MyClass mc2
不会导致另一个实例化,而是使用现有的实例化


所以这实际上取决于模板使用了多少类型。但这与使用不同的非模板类没有什么不同,这也会增加代码的大小。底线-我不担心。

除了@Als和@eran给出的答案外:


编译器和链接器将共同工作,找出给定类/函数的两种或不同数据类型的相同代码,如果他们找到相似的代码,即不依赖于数据类型,他们可能会创建该代码的一个副本。代码可能是类的方法、某些函数或方法/函数的某个部分。

谢谢,这意味着该类型被忽略,不是吗?@Baby Dolphin:这很重要,每个类型都会生成一个模板函数/类的副本,请检查更新的答案。@Baby-另一方面,如果你没有模板,你将不得不为每种类型自己编写一次代码。但是如果你在多个翻译单元中说
MyClass
,会怎么样?会有重复的代码吗?这就是LTO发挥作用的地方吗?不,实现必须删除重复项(使用未指定的魔法)。LTO更多的是关于跨文件边界优化。@宝贝,LTO是。未指定的魔法指的是链接器删除重复实例化的方式,如果它们存在于不同的编译单元上-如果两个cpp文件中都有
MC
,模板会在两个cpp文件上都实例化吗?如果是这样的话,两者是否都存在于最终的exe中,与我上面写的内容相矛盾?后者的答案当然不是……:)必须消除重复的实例化,但如何消除取决于编译器的实现。@eran:不是这样的。它们可以被消除,但不需要。唯一的要求是指向同一方法的指针比较相等。事实上,使用内联时,将存在多个副本,甚至可能只有一个TU。@MSalters:I认为
eran
指的是符号不能在结果库/可执行文件中复制的事实。内联将复制代码,但不会复制函数/类。谢谢你I’我想多问一点,但我现在困了。现在是3点50分,我一整天都没睡,否则我会生病的。几个小时后再见,至少我读到的是错误的。如果
void MC::foo()
void MC::bar()
void MC::baz()
相同,则链接器必须确保
&MC::foo!=&MC::条形码
。但由于无法比较
void MC::*(void)
void MC::*(void)
指针,它可能会消除
void MC::baz()
。你不能比较合法的指针并注意到这一点。我并没有说两个函数是否相同。我说过,如果同一函数的实现,对于两个或多个数据类型是相同的(或部分),那么编译器/链接器可以使用相同的代码段,而不是为相同的代码段进行冗余汇编。