如何在 C++ 模块系统中处理模板?
How are templates handled in C++ module system?
我正在看论文A Module System for C++
了解 C++ 模块,这是 C++ 的一项提议功能。
我无法完全理解此模块架构将如何导出模板。
有什么想法吗?
目前C++实现实际上只有两种"things"对应于代码:我们人类编写和编辑的源代码,以及编译器根据源代码吐出的汇编。
因为 C++ 模板是 "reified",每个模板实例化都会产生单独的程序集。因此,不能在定义模板的地方生成程序集,只能在使用模板的地方生成程序集。这就是为什么模板必须在头文件中,这样它们基本上可以被复制粘贴到使用点(这就是所有#include 的真正含义)。
想法是对代码进行第三种表示。想象一下,编译器在内部有某种内部表示 after 它已经解析了代码但是 before 它开始生成汇编。它产生的 "thing" 最终是抽象语法树 (AST) 的某种表示形式。它基本上就是您的程序,从对人类最简单的形式映射到对计算机最简单的形式。
这大致就是模块背后的想法(或至少是它们的实现)。你拿出你的代码,吐出某种代表 AST 的文件。此 AST 是您程序的完整表示,因此它是完全无损的。它知道关于你声明的模板的一切,等等。当一个模块被加载时,它只会加载这个文件,编译器可以使用它,就好像它拥有所有可用的源代码一样。但是,将人类可读源代码转换为这个 AST 的步骤实际上是一个相当昂贵的步骤。从 AST 开始会快很多。
如果您只有一个翻译单元,这会比较慢。毕竟,解析 -> codegen 还是比解析 -> 序列化 -> 反序列化 -> codegen 快。但是假设你有 10 个翻译单元,它们都是 #include 向量。您将解析 vector 中的代码 10 次。此时,serializing/deserializing 的额外成本被您只需解析一次这一事实所抵消(并且反序列化可以比解析快得多;这种数据格式将专门设计用于快速反序列化,而源代码被设计为可读、向后兼容等)。
某种意义上的预编译头文件是模块的预览:https://clang.llvm.org/docs/PCHInternals.html
我正在看论文A Module System for C++ 了解 C++ 模块,这是 C++ 的一项提议功能。
我无法完全理解此模块架构将如何导出模板。
有什么想法吗?
目前C++实现实际上只有两种"things"对应于代码:我们人类编写和编辑的源代码,以及编译器根据源代码吐出的汇编。
因为 C++ 模板是 "reified",每个模板实例化都会产生单独的程序集。因此,不能在定义模板的地方生成程序集,只能在使用模板的地方生成程序集。这就是为什么模板必须在头文件中,这样它们基本上可以被复制粘贴到使用点(这就是所有#include 的真正含义)。
想法是对代码进行第三种表示。想象一下,编译器在内部有某种内部表示 after 它已经解析了代码但是 before 它开始生成汇编。它产生的 "thing" 最终是抽象语法树 (AST) 的某种表示形式。它基本上就是您的程序,从对人类最简单的形式映射到对计算机最简单的形式。
这大致就是模块背后的想法(或至少是它们的实现)。你拿出你的代码,吐出某种代表 AST 的文件。此 AST 是您程序的完整表示,因此它是完全无损的。它知道关于你声明的模板的一切,等等。当一个模块被加载时,它只会加载这个文件,编译器可以使用它,就好像它拥有所有可用的源代码一样。但是,将人类可读源代码转换为这个 AST 的步骤实际上是一个相当昂贵的步骤。从 AST 开始会快很多。
如果您只有一个翻译单元,这会比较慢。毕竟,解析 -> codegen 还是比解析 -> 序列化 -> 反序列化 -> codegen 快。但是假设你有 10 个翻译单元,它们都是 #include 向量。您将解析 vector 中的代码 10 次。此时,serializing/deserializing 的额外成本被您只需解析一次这一事实所抵消(并且反序列化可以比解析快得多;这种数据格式将专门设计用于快速反序列化,而源代码被设计为可读、向后兼容等)。
某种意义上的预编译头文件是模块的预览:https://clang.llvm.org/docs/PCHInternals.html