c++ - C++ 编译器会为每个模板类型生成代码吗?

标签 c++ templates

我有两个关于 C++ 模板的问题。假设我已经编写了一个简单的列表,现在我想在我的程序中使用它来存储指向不同对象类型(A*、B* ... ALot*)的指针。我的同事说,对于每种类型,都会生成一段专用代码,即使所有指针实际上都具有相同的大小。

如果这是真的,有人能解释一下为什么吗?例如,在 Java 中,泛型与 C++ 中的指针模板具有相同的目的。泛型仅用于预编译类型检查,并在编译前被剥离。当然,所有内容都使用相同的字节码。

第二个问题是,char和short是否也会生成专用代码(考虑到它们都具有相同的大小并且没有专门化)。

如果这有什么不同,我们正在谈论嵌入式应用程序。

我发现了一个类似的问题,但没有完全回答我的问题:Do C++ template classes duplicate code for each pointer type used?

非常感谢!

最佳答案

I have two questions about templates in C++. Let's imagine I have written a simple List and now I want to use it in my program to store pointers to different object types (A*, B* ... ALot*). My colleague says that for each type there will be generated a dedicated piece of code, even though all pointers in fact have the same size.

是的,这相当于把两个函数都写好了。

一些链接器会检测到相同的函数,并消除它们。一些库知道它们的链接器没有此功能,并将通用代码分解为单个实现,仅在通用代码周围留下一个强制转换包装器。即 std::vector<T*>特化可以将所有工作转发给std::vector<void*>然后在出去的路上施法。

现在,comdat 折叠很微妙:让你认为相同的函数相对容易,但最终却不相同,所以生成了两个函数。作为玩具示例,您可以通过 typeid(x).name() 打印类型名称。 .现在每个版本的功能都是不同的,它们不能被淘汰。

在某些情况下,您可能会认为这是一个不同的运行时属性,因此会创建相同的代码,并删除相同的函数——但聪明的 C++ 编译器可能会弄清楚您做了什么,使用 as-if 规则并将其变成编译时检查,并阻止不完全相同的函数被视为相同。

If this is true, can somebody explain me why? For example in Java generics have the same purpose as templates for pointers in C++. Generics are only used for per-compile type checking and are stripped down before compilation. And of course the same byte code is used for everything.

不,他们不是。泛型大致相当于C++的类型删除技术,比如what std::function<void()>确实存储任何可调用对象。在 C++ 中,类型删除通常通过模板完成,但并非所有模板的使用都是类型删除!

C++ 用模板做的本质上不是类型删除的事情通常不可能用 Java 泛型做。

在 C++ 中,您可以使用模板创建指针的类型删除容器,但是 std::vector不会那样做——它会创建一个实际的指针容器。这样做的好处是所有类型检查 std::vector是在编译时完成的,因此不必进行任何运行时检查:安全类型删除 std::vector可能需要运行时类型检查和相关的开销。

Second question is, will dedicated code be also generated for char and short (considering that they both have the same size and there are no specialization).

它们是不同的类型。我可以编写与 char 行为不同的代码或 short值(value)。例如:

std::cout << x << "\n";

x 是 short , 这会打印一个整数,其值为 x -- 与 x作为char , 这将打印对应于 x 的字符.

现在,几乎所有的模板代码都存在于头文件中,并且隐含地是inline .同时 inline并不意味着大多数人认为的意思,它确实意味着编译器可以轻松地将代码提升到调用上下文中。

If this makes any difference, we are talking about embedded applications.

真正不同的是您的特定编译器和链接器是什么,以及它们激活了哪些设置和标志。

关于c++ - C++ 编译器会为每个模板类型生成代码吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15599474/

相关文章:

c++ - GLSL - 在 SSB 中解压 (V2)

c++ - 使用 ADO 插入单个记录的有效方法

c++ - 有关清理此终止条件的建议

templates - xslt 条件增量

模板调用之间的 C++ 转换

c++ - 代码在 CodeBlocks 中工作,但在 linux 中编译时出错

c++ - 带有模板参数的专门部分化

ajax - 在服务器和客户端之间共享 mustache/mustache 模板。 ASP.NET MVC

templates - 如何使用特定键访问该结构映射中的结构字段值

c++ - 具有从属限定标识的类成员 using-declaration 是否应该是从属名称?