[module.interface] (original) (raw)
10 Modules [module]
10.2 Export declaration [module.interface]
An export-declaration shall inhabit a namespace scope and appear in the purview of a module interface unit.
An export-declaration shall not appear directly or indirectly within an unnamed namespace or a private-module-fragment.
[Note 1:
An export-declaration does not establish a scope.
— _end note_]
A declaration is exported if it is declared within an export-declaration and inhabits a namespace scope or it is
- a namespace-definition that contains an exported declaration, or
- a declaration within a header unit ([module.import]) that introduces at least one name.
If an exported declaration is not within a header unit, it shall not declare a name with internal linkage.
[Example 1:
Source file "a.h":export int x;
Translation unit #1:module;#include "a.h" export module M;export namespace {} namespace { export int a2; } export static int b; export int f(); export namespace N { } export using namespace N; — _end example_]
If an exported declaration is a using-declaration ([namespace.udecl]) and is not within a header unit, all entities to which all of theusing-declarators ultimately refer (if any) shall have been introduced with a name having external linkage.
[Example 2:
Source file "b.h":int f();
Importable header "c.h":int g();
Translation unit #1:export module X;export int h();
Translation unit #2:module;#include "b.h" export module M;import "c.h";import X;export using ::f, ::g, ::h; struct S;export using ::S; namespace N { export int h();static int h(int); } export using N::h; — _end example_]
[Note 2:
These constraints do not apply to type names introduced by typedef declarations and alias-declarations.
[Example 3: export module M;struct S;export using T = S; — _end example_]
— _end note_]
A redeclaration of an entity Xis implicitly exported if X was introduced by an exported declaration; otherwise it shall not be exported unless it is a namespace.
[Example 4: export module M;struct S { int n; };typedef S S;export typedef S S; export struct S; namespace N { void f();} namespace N { export void g();} — _end example_]
[Note 3:
Names introduced by exported declarations have either external linkage or no linkage; see [basic.link].
Namespace-scope declarations exported by a module can be found by name lookup in any translation unit importing that module ([basic.lookup]).
Class and enumeration member names can be found by name lookup in any context in which a definition of the type is reachable.
— _end note_]
[Example 5:
Interface unit of M:export module M;export struct X { static void f();struct Y { };};namespace { struct S { };} export void f(S); struct T { };export T id(T); export struct A; export auto rootFinder(double a) { return [=](double x) { return (x + a/x)/2; };} export const int n = 5;
Implementation unit of M:module M;struct A { int value;};
Main program:import M;int main() { X::f(); X::Y y; auto f = rootFinder(2); return A{45}.value; } — _end example_]
[Note 4:
[Example 6: export module M;int g;export namespace N { int x; using ::g; } — _end example_]
— _end note_]