如何将第三方库打包为C++20模块以规避import std冲突?
关于C++20模块打包第三方库与
import std;的冲突解决方法 背景
我在Windows平台尝试用C20模块加速构建,实测下来比PCH更快。目前基于最新MSVC 17和CMake做测试,还用到了C23的import std;特性——我清楚这些都是前沿特性,仅作测试使用,同时需要保留和传统头文件包含方式的向后兼容性。
MSVC17对模块的支持已经比较完善,CMake最新版本也支持import std;,所以我打算推进这个方案,但遇到了命名冲突问题:因为使用import std;,我希望完全避免包含STL头文件,但将fmt、nlohmann_json这类第三方库打包为模块时,它们的头文件里包含了不少STL头,从而和import std;产生冲突。
已尝试的方案
我参考了CppCon上的模块演讲示例,试着把第三方头文件放在模块的export块中,但这个方法对我无效:
// 全局模块片段,可放置#include指令 module; // 此处包含的头文件不会导出给客户端 // 全局模块片段后必须紧跟模块声明 export module nlohmann_json; extern "C++" { export { #include <nlohmann/json.hpp> } } module: private; // 也可以在这里包含头文件,但同样不会导出给客户端
我的测试代码如下:
#include <gtest/gtest.h> import nlohmann_json; TEST(CxxModuleTest, nlohman_json) { nlohmann::json j = { {"pi", 3.141}, {"happy", true}, {"name", "Niels"}, {"nothing", nullptr}, {"answer", { {"everything", 42} }}, {"list", {1, 0, 2}}, {"object", { {"currency", "USD"}, {"value", 42.99} }} }; EXPECT_EQ(j["pi"], 3.141); EXPECT_EQ(j["happy"], true); EXPECT_EQ(j["name"], "Niels"); EXPECT_EQ(j["nothing"], nullptr); EXPECT_EQ(j["answer"]["everything"], 42); EXPECT_EQ(j["list"][0], 1); EXPECT_EQ(j["list"][1], 0); EXPECT_EQ(j["list"][2], 2); EXPECT_EQ(j["object"]["currency"], "USD"); EXPECT_EQ(j["object"]["value"], 42.99); }
编译时出现如下错误:
'#include <filename>' in the purview of module 'module-name-1' appears erroneous. Consider moving that directive before the module declaration, or replace the textual inclusion with 'import <filename>;'.
当前临时解决方法
目前我只能手动逐个导出需要的类型,直到编译通过,这个过程全靠试错,非常繁琐。
问题
有没有更通用、高效的方法来解决这个冲突问题?
内容的提问来源于stack exchange,提问作者JuliusCaesar
相关产品推荐
相关产品推荐

