如何在C++模块系统中处理模板?
How are templates handled in C++ module system?
我正在阅读论文A Module System forC++理解C++模块,这是C++的一个建议功能。
我无法完全理解此模块架构将如何导出模板。
有什么想法吗?
目前C++实现实际上只有两个与代码对应的"东西":我们人类编写和编辑的源代码,以及编译器根据源代码吐出的汇编。
由于C++模板是"化"的,因此将为每个模板实例化吐出单独的程序集。因此,不能在定义模板的位置生成程序集,而只能在使用模板的位置生成程序集。这就是为什么模板必须位于头文件中,以便基本上可以将它们复制粘贴到使用点(这就是 #include 的全部内容)。
这个想法是有代码的第三种表示形式。想象一下,编译器在内部解析代码后但在开始生成程序集之前具有某种内部表示形式。它产生的"事物"最终是抽象语法树(AST)的某种表示。它基本上完全是你的程序,从人类最简单的形式映射到计算机最简单的形式。
这大致是模块(或至少是它们的实现)背后的想法。你拿起你的代码,然后吐出某种代表 AST 的文件。此 AST 完全表示您的程序,因此它是完全无损的。它知道有关您声明的模板的所有信息,依此类推。加载模块时,它只会加载此文件,编译器可以完全使用它,就好像它拥有所有可用的源代码一样。但是,将人类可读源转换为此 AST 的步骤实际上是一个非常昂贵的步骤。从 AST 开始可以快得多。
如果您只有一个翻译单元,这会更慢。毕竟,解析 -> codegen 仍然比解析 -> 序列化 -> 反序列化 -> codegen 更快。但是假设你有 10 个翻译单元,它们都 #include 向量。您将解析向量中的代码 10 次。在这一点上,序列化/反序列化的额外成本被你只需要解析一次的事实所抵消(反序列化可以比解析快得多;这种数据格式将专门设计用于快速反序列化,而源代码被设计为可读、向后兼容等)。
从某种意义上说,预编译的标头是模块的预览:https://clang.llvm.org/docs/PCHInternals.html
- 错误处理.将系统错误代码映射到泛型
- C++事件系统 - 多态事件和事件处理程序
- clang++ 是否以更轻松的方式处理系统标头?
- Boost进程"系统"功能中的错误处理
- 即使在多任务处理时,添加用户时间 + 系统时间(来自 shell 的时间命令)是否是一种可靠的措施?
- 静态链接如何处理系统文件?
- 如何在C++模块系统中处理模板?
- C#/C++:启动应用程序并处理其对系统的I/O调用
- 组件实体系统-输入处理
- 未处理的异常:系统.AccessViolationException:试图读取或写入受保护的内容
- 正确处理字节对齐问题 - 通过UDP在16位嵌入式系统和32位桌面之间
- 如何处理具有完全不同的构建系统的第三方库
- 如何处理系统链路控制的NM_CLICK
- 未处理的异常:系统.访问违规异常:尝试读取或写入受保护的内存
- 使用系统调用处理退出状态
- 处理系统键关闭消息时禁用烦人的声音
- 做系统();命令的工作方式与批处理命令完全相同
- 不同平台上的系统异常处理
- Win32:更多"object oriented"窗口消息处理系统
- 为请求处理系统提供灵活、无阻碍的参数传递