Home > Back-end >  Why does exporting a type alias such as std::vector<std::string> in a module allow use of both
Why does exporting a type alias such as std::vector<std::string> in a module allow use of both

Time:05-02

I am currently using Visual Studio 2022 Update 17.1.6, and I found something interesting with exporting type alias. For reasons I don't understand, when I export a type alias for some data type such as std::vector<std::string> in a module interface file, I can use both std::vector<> and std::string in the file that imported it. For example:

modInterface.ixx

export module words;
import <iostream>
import <vector>;
import <string>;
...
export using Words = std::vector<std::string>;
...

In an internal partition:

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;
...

My first thought was that since Words is a type alias, exporting it would mean exporting std::vector<> and std::string, but since std::vector<> is a template, why is it not the case that only the instantiation of it (std::vector<std::string>) is exported?

CodePudding user response:

When one part of a module imports another, all declarations not affected by internal linkage are available as if they were exported. That applies even to import declarations (and to the implicit import of a module by its non-partition implementation units), so the import <vector>; etc. are available in the words:wordsIP partition. The export has nothing to do with it at all.

CodePudding user response:

Here's a funny thing about modules: export declarations only matter for code outside of a module.

If you import a module unit that is part of the same module as yourself, you have access to all of the declarations in that module unit. This allows you to have "private" declarations which are not exported to the module's interface, but are still accessible to other code within the module. This 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 units are not special in this regard. You imported those header units, so they are imported by your primary module interface. Therefore, any module implementations for that module that import your primary module interface will see them.

  • Related