C++20にモジュールが入ることが決まりました。
モジュールを使っていない古いコードとの互換性のため、いくつかの機能が追加されています1。その中の1つに、モジュールと #include
の中間的な機能、Header unitsがあります。
Header unitsとは
import構文でモジュール名の代わりにファイル名を書くと、そのファイル内の宣言とマクロが使用可能になります2。
#include "some-header.h"
import some_module;
import "some-header.h"; // <some-header.h>も可
/* ここではsome-header.h内の宣言やマクロが見える */
マクロも保存されるので、従来の #include
とほとんど同じであると言って良いでしょう。
(import
はプリプロセッサディレクティブではなく、おそらくはコンパイル時に処理されるという違いはあります)
ライブラリがモジュールで提供されていないとしても、Header unitsを使えば #include
をやめることができます。
再エクスポート
Header unitsをインポートしても、その中の宣言がインポートする側のモジュールに属することにはなりません3。
(これ自体はモジュール一般の仕様です)
Header unitsも普通のモジュールと同じように再エクスポートすることができます。
export module foo;
export import "some-header.h";
しかし、再エクスポートしてもヘッダーファイル中のマクロはエクスポートされません4。
ヘッダーファイルをモジュールでラップすることが簡単にできるので、この仕様はヘッダーとモジュールの両方を提供する場合に便利だと思われます。移行の過渡期にはそのようなライブラリが増えるかもしれません。
Importable Header
どんなヘッダーファイルでもインポートできるわけではありません。
Header unitsとしてインポートできるヘッダーの集合をimportable headerといいます。
何がimportable headerかは処理系定義です。
C++20では、importable headerを#include
した場合はインポートに置き換わります。
参考文献
謝辞
この記事はC++20を相談しながら調べる会 #1の結果として書かれました。
-
This proposal provides several features to support interoperation between modular code and traditional non-modular code. ↩
-
the interface of the header is extracted and made available for import, and any macros defined by preprocessing the header are saved so that they can be made available to importers ↩
-
Declarations from code in a header unit are not owned by any module. ↩
-
when a header unit is re-exported, macros are not exported. ↩