C++模块、标准库、第三方库和一个定义规则

dxpyg8gm  于 2023-08-09  发布在  其他
关注(0)|答案(1)|浏览(107)

每隔一两年,我都会决定尝试使用C++模块,但每次我都会遇到问题,通常是编译器。但这次我的问题似乎是在规范本身,我似乎找不到解决它的方法。
考虑一个头文件为foo.hpp的第三方库。在foo.hpp中,它包括<string>。假设由于某种原因(可能是因为奇怪的宏使用),foo.hpp不能被编译为头单元,所以它必须是#include d。我的问题来自于试图同时使用这个库和<string>
想法一:

module;

#include <foo.hpp>

export module A;

import <string>;

...

字符串
据我所知,这里的问题是<string>包含在foo.hpp中,但是在导入<string>时,包含<string>的头保护没有应用,导致了odr违规。
想法二:

export module A;

import <string>;
#include <foo.hpp>

...


因为头单元定义了宏,所以这修复了odr冲突,当foo.hpp包含<string>时,头保护就会启动。然而,这最终将foo.hpp的所有内容定义为模块A中的实体,这是不正确的,会导致各种问题。
想法三:

module;

#include <foo.hpp>

export module A;

...


这背后的想法是,如果foo.hpp已经包含了<string>,为什么还要再尝试一次呢?问题是,这在更复杂的情况下不起作用。假设我不是导入<string>,而是导入了另一个模块,该模块可以导出导入的<string>?或者更复杂的东西?最后,这个解决方案无法扩展。
想法四:

module;

#include <string>
#include <foo.hpp>

export module A;

...


这是可行的,但由于显而易见的原因,这并不理想。
我的问题是,有没有办法解决这个问题?或者C模块不可能与非模块化的第三方库一起使用,这基本上使C模块无用?
请注意,我在寻找C标准的内容,而不是任何特定的实现,因为当涉及到模块时,实现仍然在弄清楚它们到底在做什么。但是,如果是“C标准不允许这样做,但是所有的实现都在一起工作,以实现一个解决方案”的形式,我会接受另一个答案。
This question以稍微不同的方式遇到了相同的问题,但问题是关于识别问题,而不是解决问题。提问者说他们会发布另一个关于如何解决它的问题,但从来没有这样做。This question基本上问了同样的问题,但它没有重点,似乎每个人都误解了他们的问题。

os8fio9y

os8fio9y1#

标准说([std.modules]/5):
标准库中的声明表示相同的实体,而不管它是通过包含头、导入头单元还是导入C++库模块来实现的。
因此,如果混合#includeimport不能很好地工作,这就是一个实现错误(一个难以修复的错误,AFAIK)。

相关问题