[module.interface] (original) (raw)
10 Modules [module]
10.2 Export declaration [module.interface]
An export-declaration shall appear only at namespace scope and only 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.
A declaration is exported if it is
- a namespace-scope declaration declared within anexport-declaration, or
- a namespace-definition that contains an exported declaration, or
- a declaration within a header unit ([module.import]) that introduces at least one name.
If the 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 {} export namespace { int a1; } namespace { export int a2; } export static int b; export int f(); export namespace N { } export using namespace N; — _end example_]
If the 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 1:
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 exported declaration of an entity is implicitly exported.
An exported redeclaration of a non-exported declaration of an entity is ill-formed.
[Example 4: export module M;struct S { int n; };typedef S S;export typedef S S; export struct S; — _end example_]
A name is exported by a module if it is introduced or redeclared by an exported declaration in the purview of that module.
[Note 2:
Exported names have either external linkage or no linkage; see [basic.link].
Namespace-scope names exported by a module are visible to name lookup in any translation unit importing that module; see [basic.scope.namespace].
Class and enumeration member names are visible to 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 3:
Redeclaring a name in an export-declarationcannot change the linkage of the name ([basic.link]).
[Example 6:
Interface unit of M:export module M;static int f(); export int f(); struct S; export struct S; namespace { namespace N { extern int x; } } export int N::x; — _end example_]
— _end note_]
[Note 4:
[Example 7: export module M;export namespace N { int x; static_assert(1 == 1); } — _end example_]
— _end note_]