Translation unit #1:export module A; export import :Foo; export int baz();
Translation unit #2:export module A:Foo; import :Internals; export int foo() { return 2 * (bar() + 1); }
Translation unit #3:module A:Internals; int bar();
Translation unit #4:module A; import :Internals; int bar() { return baz() - 10; } int baz() { return 30; }
Translation unit #1:module B:Y; // does not implicitly import B int y();
Translation unit #2:export module B; import :Y; // OK, does not create interface dependency cycle int n = y();
Translation unit #3:module B:X1; // does not implicitly import B int &a = n; // error: n not visible here
Translation unit #4:module B:X2; // does not implicitly import B import B; int &b = n; // OK
Translation unit #5:module B; // implicitly imports B int &c = n; // OK — end example]
Source file "a.h":export int x;
Translation unit #1:module; #include "a.h" // error: declaration of x is not in the // purview of a module interface unit export module M; export namespace {} // error: namespace has internal linkage namespace { export int a2; // error: export of name with internal linkage } export static int b; // error: b explicitly declared static export int f(); // OK export namespace N { } // OK export using namespace N; // OK — end example]
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; // OK struct S; export using ::S; // error: S has module linkage namespace N { export int h(); static int h(int); // #1 } export using N::h; // error: #1 has internal linkage — end example]
Interface unit of M:export module M; export struct X { static void f(); struct Y { }; }; namespace { struct S { }; } export void f(S); // OK struct T { }; export T id(T); // OK export struct A; // A exported as incomplete export auto rootFinder(double a) { return [=](double x) { return (x + a/x)/2; }; } export const int n = 5; // OK, n has external linkage
Implementation unit of M:module M; struct A { int value; };
Main program:import M; int main() { X::f(); // OK, X is exported and definition of X is reachable X::Y y; // OK, X::Y is exported as a complete type auto f = rootFinder(2); // OK return A{45}.value; // error: A is incomplete } — end example]
Interface unit of M1:export module M1; import M2;
Interface unit of M2:export module M2; import M3;
Interface unit of M3:export module M3; import M1; // error: cyclic interface dependency M3 →M1 →M2 →M3 — end example]
Source file "foo.h":namespace N { struct X {}; int d(); int e(); inline int f(X, int = d()) { return e(); } int g(X); int h(X); }
Module M interface:module; #include "foo.h" export module M; template<typename T> int use_f() { N::X x; // N::X, N, and :: are decl-reachable from use_f return f(x, 123); // N::f is decl-reachable from use_f, // N::e is indirectly decl-reachable from use_f // because it is decl-reachable from N::f, and // N::d is decl-reachable from use_f // because it is decl-reachable from N::f // even though it is not used in this call } template<typename T> int use_g() { N::X x; // N::X, N, and :: are decl-reachable from use_g return g((T(), x)); // N::g is not decl-reachable from use_g } template<typename T> int use_h() { N::X x; // N::X, N, and :: are decl-reachable from use_h return h((T(), x)); // N::h is not decl-reachable from use_h, but // N::h is decl-reachable from use_h<int> } int k = use_h<int>(); // use_h<int> is decl-reachable from k, so // N::h is decl-reachable from k
Module M implementation:module M; int a = use_f<int>(); // OK int b = use_g<int>(); // error: no viable function for call to g; // g is not decl-reachable from purview of // module M's interface, so is discarded int c = use_h<int>(); // OK — end example]
Translation unit #1:export module stuff; export template<typename T, typename U> void foo(T, U u) { auto v = u; } export template<typename T, typename U> void bar(T, U u) { auto v = *u; }
Translation unit #2:export module M1; import "defn.h"; // provides struct X {}; import stuff; export template<typename T> void f(T t) { X x; foo(t, x); }
Translation unit #3:export module M2; import "decl.h"; // provides struct X; (not a definition) import stuff; export template<typename T> void g(T t) { X *x; bar(t, x); }
Translation unit #4:import M1; import M2; void test() { f(0); g(0); }
Translation unit #1:export module M:A; export struct B;
Translation unit #2:module M:B; struct B { operator int(); };
Translation unit #3:module M:C; import :A; B b1; // error: no reachable definition of struct B
Translation unit #4:export module M; export import :A; import :B; B b2; export void f(B b = B());
Translation unit #5:import M; B b3; // error: no reachable definition of struct B void g() { f(); } // error: no reachable definition of struct B — end example]
Translation unit #1:export module A; struct X {}; export using Y = X;
Translation unit #2:import A; Y y; // OK, definition of X is reachable X x; // error: X not visible to unqualified lookup — end example]