每隔一两年,我都会决定尝试使用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基本上问了同样的问题,但它没有重点,似乎每个人都误解了他们的问题。
1条答案
按热度按时间os8fio9y1#
标准说([std.modules]/5):
标准库中的声明表示相同的实体,而不管它是通过包含头、导入头单元还是导入C++库模块来实现的。
因此,如果混合
#include
和import
不能很好地工作,这就是一个实现错误(一个难以修复的错误,AFAIK)。