我有两个关于 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/