【发布时间】:2021-09-27 05:49:04
【问题描述】:
我们有 C++20 中的模块,我们可以在我们的代码中完全删除 #include 吗?
例如,我们可以写
import boost.asio;
...
代替
#include <boost/asio.hpp>
...
过去我们需要这些步骤来安装一个库:
- 将所有源文件 (.cpp) 编译成对象 (.o)。
- 将它们打包到库(.a 或 .so)中。
- 将标头安装到
/usr/include。 - 将库文件安装到
/usr/lib。
在 C++20 中,我们可以:
- 编译所有源文件,但每个源文件可能生成一个对象 (.o) 和一个编译模块接口 (CMI)。对于 gcc,它们具有 .gcm 后缀。
- 将对象 (.o) 打包到库(.a 或 .so)中。
- 将库文件安装到
/usr/lib。 - 将 CMI 安装到某个路径中。
但是使用 CMI 发布您的库会导致问题:
- 我们没有专门的文件夹来放置 CMI(我猜可能是
/usr/include/c++-modules)。 - 不同的编译器产生不同的 CMI。开发人员为他们的库提供不同版本的 CMI 是很糟糕的。
- 如果我们根据模块 B 编译模块 A,但使用不同的编译标志怎么办?不同的标志可能不会引起您的注意,但可能会导致潜在的错误。
这不是用 CMI 替换标头的好方法。那么我们如何才能从 C++ 中完全删除标头呢?
我不是在谈论标准库,因为模块化 c++ 标准库是在 c++23 中引入的。
【问题讨论】:
-
对于不同的标志,您已经遇到了二进制 (.a/.so) 的问题...
-
鉴于编译器和工具支持介于不存在和处于起步阶段之间,我认为这个问题还早了 5 年。
-
@Jarod42 我对 OP 抱怨的解释是,从单头文件+多二进制文件到多 CMI+多二进制文件感觉像是倒退了一步。
-
今天要做这件事是非常雄心勃勃的。我建议等到您使用的编译器都支持该功能,并且您已验证该功能适用于您的项目。
-
在系统级别“安装库”的想法让我觉得很奇怪。库和依赖项应该是每个项目的,而不是每个系统的。如果两个项目共享完全相同的库依赖项,则您的库管理代码可以共享它。这适用于
.o文件;两个不同的编译器可以编译不兼容的.o或.dylib或来自同一源的任何文件。他们只是按照惯例同意。
标签: c++ c++20 c++-modules