提问人:non-user38741 提问时间:12/29/2022 最后编辑:non-user38741 更新时间:12/29/2022 访问量:610
仅标头库作为模块?
Header only library as a module?
问:
我正在创作一个仅模板化的标题库。它没有状态,没有全局变量,没有需要编译的.cpp。
是否可以将其作为模块导出/使用?如何?有什么好处?有哪些陷阱?
我可能希望用户拥有一些方便的宏。那些呢?
我找到了一个用于满足模块和老式情况的示例。我想我想避免这种情况。#ifdef ...
答:
我找到了一个使用...以迎合模块和老式案例。我想我想避免这种情况。
#ifdef
从广义上讲,这不是最好的方法。你可以通过只将标题作为标题单元导入来做到这一点,但你会丢失模块的一些重要方面。如果你想让你的模块版本运行良好,你将需要做有限的工作。import <header_file.hpp>;
#define
几乎每个仅标头库都会有一些声明被视为库的一部分,但它也会有一些不是的声明。它们通常被放入命名空间中,或者尝试以其他方式对用户隐藏它们。detail
模块具有执行此操作的机制:。或者更确切地说,他们有办法不把东西放在你的界面中:不要。但这需要用关键字明确标记你的界面......这在非模块构建中不起作用。因此,您需要一个宏来说明构建是否是模块构建,以便您可以有一个解析为或无解析为任何内容的宏。export
export
export
#define
export
您可以尝试导出所有内容,但这可以...令人不快的副作用。export namespace my_namespace {};
您可能还需要显式定义导出类的某些类成员,因为模块不会像非模块生成那样隐式定义非模板类的成员。幸运的是,添加在非模块构建上可以正常工作。inline
inline
inline
为它编写一个仅标头库和一个模块接口文件,以便用户可以包含他们喜欢的任何一个,这并不难。但它确实需要一些小心,为了最好地利用模块功能,您应该使用一些宏。
主模块接口单元如下所示:
module; //Begin global module fragment.
<external header includes>
export module MyModuleName; //Begin the actual module purview
#define MY_MODULE_NAME_EXPORT export;
#include "my_header1.hpp"
#include "my_header2.hpp"
这非常重要。您需要库明确包含的每个文件。如果包含 C++ 标准库的某些部分,请在此处包含它们。<external header includes>
#include
这样做的目的是阻止这些标头将这些标头的内容推入模块的权限范围。你希望你所包含的库是唯一被推入模块的代码。因此,您可以将这些标头包含在全局模块片段中,并使用它们的 include-guard 来防止以后包含。
是的,这确实意味着您必须保留这些标头的两个单独列表。您可以编写一个工具来查看所有标题并为您构建该列表,但无论如何,它仍然是您需要拥有的东西。
在库标头的顶部,在任何包含保护之后,您需要具有以下内容:
#ifndef MY_MODULE_NAME_EXPORT
#define MY_MODULE_NAME_EXPORT
#endif
这允许您使用以下命令装饰要导出的任何内容:MY_MODULE_NAME_EXPORT
MY_MODULE_NAME_EXPORT void some_function()
{
...
}
如果你在模块构建中,这将导出函数。如果你不是,那么它就不会。
评论
Is it possible to export/consume this as a module?
是的。