为什么在模块中导出 std::vector<std::string> 等类型别名允许在某些内部分区中同时使用 std::vector 和 std::string?
Why does exporting a type alias such as std::vector<std::string> in a module allow use of both std::vector and std::string in some internal partition?
我目前正在使用 Visual Studio 2022 更新 17.1.6,我发现导出类型别名很有趣。由于我不明白的原因,当我在模块接口文件中导出某些数据类型(例如 std::vector<std::string>
的类型别名时,我可以在文件中同时使用 std::vector<>
和 std::string
导入它。例如:
modInterface.ixx
export module words;
import <iostream>
import <vector>;
import <string>;
...
export using Words = std::vector<std::string>;
...
在内部分区中:
modInternalPartition.cpp
module words:wordsIP;
import words;
//This compiles as expected
Words wordStorage;
//Why does my compiler sees below as correct, and compiles it without error?
std::vector<int> numStorage = { 1, 2, 3, 4 };
//Why does my compiler also sees below as correct, and compiles it without error?
std::string text = "This dish is tasty";
//This would produce an error, which is expected since I did not export import <iostream> in modInterface.ixx
std::cout << text;
...
我的第一个想法是,既然Words
是一个类型别名,导出它就意味着导出std::vector<>
和std::string
,但是既然std::vector<>
是一个模板,为什么不是只导出它的实例化(std::vector<std::string>
)吗?
当模块的一个 部分 导入另一个时,所有不受内部链接影响的声明都可用,就好像它们被 导出 一样。这甚至适用于 import
声明(以及通过其 non-partition 实现单元隐式导入模块),因此 import <vector>;
等 是在 words:wordsIP
分区中可用。 export
与它完全无关。
关于模块有一件有趣的事情:export
声明只对模块外部 的代码有影响。
如果您导入与您属于同一模块的模块单元,您可以访问该模块单元中的所有 声明。这允许您拥有“私有”声明,这些声明不会导出到模块的接口,但仍然可以被模块中 中的其他代码访问。这个includes module imports:
Additionally, when a module-import-declaration in a module unit of some module M imports another module unit U of M, it also imports all translation units imported by non-exported module-import-declarations in the module unit purview of U.
Header单位在这方面并不特殊。您导入了那些 header 单元,因此它们由您的主模块接口导入。因此,导入您的主模块接口的该模块的任何模块实现都将看到它们。
我目前正在使用 Visual Studio 2022 更新 17.1.6,我发现导出类型别名很有趣。由于我不明白的原因,当我在模块接口文件中导出某些数据类型(例如 std::vector<std::string>
的类型别名时,我可以在文件中同时使用 std::vector<>
和 std::string
导入它。例如:
modInterface.ixx
export module words;
import <iostream>
import <vector>;
import <string>;
...
export using Words = std::vector<std::string>;
...
在内部分区中:
modInternalPartition.cpp
module words:wordsIP;
import words;
//This compiles as expected
Words wordStorage;
//Why does my compiler sees below as correct, and compiles it without error?
std::vector<int> numStorage = { 1, 2, 3, 4 };
//Why does my compiler also sees below as correct, and compiles it without error?
std::string text = "This dish is tasty";
//This would produce an error, which is expected since I did not export import <iostream> in modInterface.ixx
std::cout << text;
...
我的第一个想法是,既然Words
是一个类型别名,导出它就意味着导出std::vector<>
和std::string
,但是既然std::vector<>
是一个模板,为什么不是只导出它的实例化(std::vector<std::string>
)吗?
当模块的一个 部分 导入另一个时,所有不受内部链接影响的声明都可用,就好像它们被 导出 一样。这甚至适用于 import
声明(以及通过其 non-partition 实现单元隐式导入模块),因此 import <vector>;
等 是在 words:wordsIP
分区中可用。 export
与它完全无关。
关于模块有一件有趣的事情:export
声明只对模块外部 的代码有影响。
如果您导入与您属于同一模块的模块单元,您可以访问该模块单元中的所有 声明。这允许您拥有“私有”声明,这些声明不会导出到模块的接口,但仍然可以被模块中 中的其他代码访问。这个includes module imports:
Additionally, when a module-import-declaration in a module unit of some module M imports another module unit U of M, it also imports all translation units imported by non-exported module-import-declarations in the module unit purview of U.
Header单位在这方面并不特殊。您导入了那些 header 单元,因此它们由您的主模块接口导入。因此,导入您的主模块接口的该模块的任何模块实现都将看到它们。