模板类是否C++使用的每种指针类型复制代码

Do C++ template classes duplicate code for each pointer type used?

本文关键字:指针 类型 代码 复制 是否 C++      更新时间:2023-10-16

据我了解,例如,如果您有std::vector<int>std::vector<float>,编译器会创建两个类,每种类型一个。因此,尽管您减少了编写的代码量,但不会减少可执行文件的大小(如果我错了,请纠正我)。

即使类型是指针,情况也一样吗?例如,实例化std::vector<SomeClass*>std::vector<SomeOtherClass*>是否必然会导致编译器为这两个实例化中的每一个生成单独的代码?

这是一个依赖于实现的假设优化,因此是允许的!

事实上,这甚至不必由编译器完成。标准库可以通过这种方式实现。例如,实现可以使用std::is_pointer,然后将所有内容推迟到单个基于 void* 的实现。(这是瘦模板习语)。事实上,在库端执行此操作似乎比编译器在实例化代码后合并代码更可行,但这也是可能的。

编译器从

模板实例化程序使用的类数。但是,为在可执行文件中生成的代码与程序中存在的类略有不同。

实际上,vector上的大多数操作都将内联。因此,可执行文件大小可能不会根据从该模板实例化的不同类的数量而发生太大变化,因为代码大小的大部分是每个函数调用站点而不是每个不同的类。但就它取决于实例化的数量而言,vector<SomeClass*>vector<SomeOtherClass*>是不同的类。

如果你显式实例化vector,那么所有的成员函数都将为该类生成。如果您寻找它,您可能会看到代码大小的差异。但通常不会显式实例化模板类,因此仅生成您使用的成员函数。

允许

编译器生成一组代码来实现模板的两个实例化,前提是生成的行为是正确的。指针类型和非指针类型可能会发生这种情况。它可以针对模板类中的每个例程(也称为"方法")独立发生。

可能很难确定何时会发生这种情况,并且编译器可能会也可能不会识别这样做的机会。

例如,如果例程只是复制一个类,就像赋值运算符通常所做的那样,那么可以对类数据具有相同大小的模板的任何实例化使用相同的代码。在某些处理器上,添加两个int对象的代码可能与添加到unsigned int对象的代码相同。

是的,你是对的。有一些方法可以减少重复,请参阅我的饮食模板演示文稿中的幻灯片 18-26。

有一点是"常识",std::vector<T*>std::vector<U*>都可以作为围绕vector_impl<void*>专业化的薄包装器实现,因此它们在可能的情况下共享相同的生成代码(这就是我在幻灯片中所说的提升),但我不认为现代 std::lib 实现实际上可以进行这种优化。当然libstdc++没有。

编译器不会"创建两个类"。相反,std::vector<int>std::vector<float>两个不同的类。不要混淆类和模板——它们是语言的核心概念!同样,std::vector<SomeClass *>std::vector<SomeOtherClass *>是两个不同的类,它们应该回答你的问题。

相关文章: