[module.global.frag] (original) (raw)
10 Modules [module]
10.4 Global module fragment [module.global.frag]
[Note 1:
Prior to phase 4 of translation, only preprocessing directives can appear in the declaration-seq ([cpp.pre]).
— _end note_]
A global-module-fragment specifies the contents of theglobal module fragment for a module unit.
The global module fragment can be used to provide declarations that are attached to the global module and usable within the module unit.
A declaration D is decl-reachable from a declaration Sin the same translation unit if
- D does not declare a function or function template andS contains anid-expression,namespace-name,type-name,template-name, orconcept-namenaming D, or
- D declares a function or function template that is named by an expression ([basic.def.odr]) appearing in S, or
- S contains a dependent call E ([temp.dep]) and D is found by any name lookup performed for an expression synthesized from Eby replacing each type-dependent argument or operand with a value of a placeholder type with no associated namespaces or entities, or
[Note 2:
This includes the lookup for operator== performed when considering rewriting an != expression, the lookup for operator<=>performed when considering rewriting a relational comparison, and the lookup for operator!=when considering whether an operator== is a rewrite target.
— _end note_] - S contains an expression that takes the address of an overload set ([over.over]) that contains D and for which the target type is dependent, or
- there exists a declaration M that is not a namespace-definitionfor which M is decl-reachable from S and either
- D is decl-reachable from M, or
- D and M declare the same entity, and D neither is a friend declaration nor inhabits a block scope, or
- D declares a namespace N and M is a member of N, or
- one of D and M declares a class or class template Cand the other declares a member or friend of C, or
- one of D and M declares an enumeration Eand the other declares an enumerator of E, or
- D declares a function or variable and M is declared in D,86or
- one of D and M declares a template and the other declares a partial or explicit specialization or an implicit or explicit instantiation of that template, or
- M declares a class template and D is a deduction guide for that template, or
- one of D and M declares a class or enumeration type and the other introduces a typedef name for linkage purposes for that type.
In this determination, it is unspecified
- whether a reference to analias-declaration,typedef declaration,using-declaration, ornamespace-alias-definitionis replaced by the declarations they name prior to this determination,
- whether a simple-template-idthat does not denote a dependent type and whose template-name names an alias template is replaced by its denoted type prior to this determination,
- whether a decltype-specifierthat does not denote a dependent type is replaced by its denoted type prior to this determination, and
- whether a non-value-dependent constant expression is replaced by the result of constant evaluation prior to this determination.
[Note 3:
A discarded declaration is neither reachable nor visible to name lookup outside the module unit, nor in template instantiations whose points of instantiation ([temp.point]) are outside the module unit, even when the instantiation context ([module.context]) includes the module unit.
— _end note_]
[Example 1: const int size = 2;int ary1[size]; constexpr int identity(int x) { return x; } int ary2[identity(2)]; template<typename> struct S;template<typename, int> struct S2;constexpr int g(int);template<typename T, int N>S<S2<T, g(N)>> f(); template<int N> void h() noexcept(g(N) == N); — _end example_]
[Example 2:
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; return f(x, 123); } template<typename T> int use_g() { N::X x; return g((T(), x)); } template<typename T> int use_h() { N::X x; return h((T(), x)); } int k = use_h<int>();
Module M implementation:module M;int a = use_f<int>(); int b = use_g<int>(); int c = use_h<int>(); — _end example_]