From 16e5b370e816cd20a7789124326a975a51fd953d Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 29 Mar 2026 23:55:08 +0200 Subject: [PATCH] P4149R1 Define "immediate context" Fixes NB US 54-100 (C++26 CD). --- source/exceptions.tex | 9 ++- source/templates.tex | 135 ++++++++++++++++++++++++------------------ 2 files changed, 80 insertions(+), 64 deletions(-) diff --git a/source/exceptions.tex b/source/exceptions.tex index 377a0a8237..465c819730 100644 --- a/source/exceptions.tex +++ b/source/exceptions.tex @@ -996,7 +996,9 @@ declaration (e.g., an explicit specialization or an overriding virtual function); -\item the function is defined; or +\item the function is defined; + +\item the function is represented by a reflection; or \item the exception specification is needed for a defaulted function that calls the function. @@ -1009,10 +1011,7 @@ \end{note} \end{itemize} The exception specification of a defaulted -function is evaluated as described above only when needed; similarly, the -\grammarterm{noexcept-specifier} of a specialization -of a templated function -is instantiated only when needed. +function is evaluated as described above only when needed. % \indextext{exception specification|)} diff --git a/source/templates.tex b/source/templates.tex index 9effb38ee5..9fe8e5e420 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -2680,31 +2680,30 @@ which shall be a class or variable template. \pnum +A \defnadj{separately instantiated}{construct} +of a templated function \tcode{F} is a +\begin{itemize} +\item default argument, +\item \grammarterm{noexcept-specifier}, or +\item \grammarterm{function-contract-specifier} +\end{itemize} +of \tcode{F}. For purposes of name lookup and instantiation, -default arguments, -\grammarterm{type-constraint}{s}, -\grammarterm{requires-clause}{s}\iref{temp.pre}, -and -\grammarterm{noexcept-specifier}{s} -of function templates -and -of member functions of class templates +separately instantiated constructs, +\grammarterm{type-constraint}{s}, and +\grammarterm{requires-clause}{s}\iref{temp.pre} are considered definitions; each -default argument, -\grammarterm{type-constraint}, -\grammarterm{requires-clause}, -or -\grammarterm{noexcept-specifier} +separately instantiated construct, +\grammarterm{type-constraint}, or +\grammarterm{requires-clause} is a separate definition which is unrelated to the templated function definition or to any other -default arguments, -\grammarterm{type-constraint}{s}, -\grammarterm{requires-clause}{s}, -or -\grammarterm{noexcept-specifier}{s}. +separately instantiated constructs, +\grammarterm{type-constraint}{s}, or +\grammarterm{requires-clause}{s}. For the purpose of instantiation, the substatements of a constexpr if statement\iref{stmt.if} are considered definitions. For the purpose of name lookup and instantiation, @@ -6649,19 +6648,6 @@ X ch; // error: incomplete type \tcode{X} \end{codeblock} \end{example} -\begin{note} -Within a template declaration, -a local class\iref{class.local} or enumeration and the members of -a local class are never considered to be entities that can be separately -instantiated (this includes their default arguments, -\grammarterm{noexcept-specifier}{s}, and non-static data member -initializers, if any, -but not their \grammarterm{type-constraint}{s} or \grammarterm{requires-clause}{s}). -As a result, the dependent names are looked up, the -semantic constraints are checked, and any templates used are instantiated as -part of the instantiation of the entity within which the local class or -enumeration is declared. -\end{note} \pnum The implicit instantiation of a class template specialization causes @@ -6681,10 +6667,6 @@ unscoped member enumerations, and member anonymous unions. \end{itemize} -The implicit instantiation of a class template specialization -does not cause the implicit instantiation of -default arguments or \grammarterm{noexcept-specifier}{s} -of the class member functions. \begin{example} \begin{codeblock} template @@ -6748,11 +6730,6 @@ implicitly instantiated when it is referenced in a context that requires a function definition to exist or if the existence of the definition affects the semantics of the program. -Unless a call is to a function template explicit specialization or -to a member function of an explicitly specialized class template, -a default argument for a function template or a member function of a -class template is implicitly instantiated when the function is -called in a context that requires the value of the default argument. \begin{note} An inline function that is the subject of an explicit instantiation declaration @@ -6883,7 +6860,25 @@ causes specializations in the default member initializer to be instantiated. \pnum -If a templated function +The separately instantiated constructs\iref{temp.decls.general} +of a templated function \tcode{F} that is either +\begin{itemize} +\item +a member of a local class or +\item +the function call operator of the closure type +of a non-generic lambda-expression +\end{itemize} +are instantiated when the declaration of \tcode{F} is instantiated. +\begin{note} +For the purposes of instantiation, +these constructs are still considered separately +from the function to which they belong. +\end{note} + +\pnum +Other than as specified above, +when a templated function \tcode{f} is called in a way that requires a default argument to be used, the dependent names are looked up, the semantics constraints are checked, @@ -6902,7 +6897,9 @@ \tcode{f}. \pnum +\begin{note} Each default argument is instantiated independently. +\end{note} \begin{example} \begin{codeblock} template void f(T x, T y = ydef(T()), T z = zdef(T())); @@ -6920,16 +6917,16 @@ \end{example} \pnum -The \grammarterm{noexcept-specifier} and \grammarterm{function-contract-specifier}s -of a function template specialization -are not instantiated along with the function declaration; -they are instantiated -when needed\iref{except.spec,dcl.contract.func}. If such a -specifier is needed but has not yet been -instantiated, the dependent names are looked up, the semantics constraints are -checked, and the instantiation of any template used in the -specifier is done as if it were being done as part -of instantiating the declaration of the specialization at that point. +Other than as specified above, +the separately instantiated constructs +of a specialization of a templated function +are instantiated only when needed\iref{except.spec,dcl.contract.func}. +When such a construct is instantiated, +the dependent names are looked up, +the semantics constraints are checked, and +the instantiation of any template used in the construct +is done as if it were being done as part of instantiating the declaration +of the specialization at that point. \pnum \begin{note} @@ -8053,20 +8050,40 @@ \end{note} Invalid types and expressions can result in a deduction failure only in the immediate context of the deduction substitution loci. +The \defnadj{immediate}{context} of a deduction substitution locus +is that deduction substitution locus, +excluding bodies of \grammarterm{lambda-expression}s and separately instantiated constructs. +\begin{example} +\begin{codeblock} +template +T* fun(T&& v); // \#1: the deduction substitution locus is the function type + // ``function of (rvalue reference to \tcode{T}) returning pointer to \tcode{T}'' + +void fun(...); // \#2 + +void test() +{ + int i; + fun(i); // selects \#2 (forming the type ``pointer to reference to \tcode{int}'' fails in \#1) +} +\end{codeblock} +\end{example} +\begin{note} +Separately instantiated constructs are excluded from the immediate contexts +even if they are instantiated at the same time. +\end{note} \begin{note} The substitution into types and expressions can result -in effects such as the instantiation of class template specializations and/or -function template specializations, the generation of implicitly-defined functions, -etc. Such effects are not in the ``immediate context'' and can result in the -program being ill-formed. +in effects such as the instantiation of template specializations, +the generation of implicitly-defined functions, etc. +Such effects are not in the immediate context +and can result in the program being ill-formed. \end{note} \pnum -When substituting into a \grammarterm{lambda-expression}, -substitution into its body is not in the immediate context. \begin{note} -The intent is to avoid requiring implementations to deal with -substitution failure involving arbitrary statements. +No \grammarterm{statement} is ever in the immediate context +of a deduction substitution locus. \begin{example} \begin{codeblock} template