|
1372 | 1372 | \end{example}
|
1373 | 1373 | \end{itemize}
|
1374 | 1374 |
|
1375 |
| -\pnum |
1376 |
| -A potentially-evaluated \grammarterm{id-expression} |
1377 |
| -that denotes an immediate function\iref{dcl.constexpr} |
1378 |
| -shall appear only |
1379 |
| -\begin{itemize} |
1380 |
| -\item as a subexpression of an immediate invocation, or |
1381 |
| -\item in an immediate function context\iref{expr.const}. |
1382 |
| -\end{itemize} |
1383 |
| - |
1384 | 1375 | \pnum
|
1385 | 1376 | For an \grammarterm{id-expression} that denotes an overload set,
|
1386 | 1377 | overload resolution is performed
|
|
7853 | 7844 | \begin{itemize}
|
7854 | 7845 | \item
|
7855 | 7846 | its innermost enclosing non-block scope is
|
7856 |
| -a function parameter scope of an immediate function, or |
| 7847 | +a function parameter scope of an immediate function, |
| 7848 | +\item |
| 7849 | +it is a subexpression of a manifestly constant-evaluated expression |
| 7850 | +or conversion, or |
7857 | 7851 | \item
|
7858 | 7852 | its enclosing statement is enclosed\iref{stmt.pre} by
|
7859 | 7853 | the \grammarterm{compound-statement} of a consteval if statement\iref{stmt.if}.
|
|
7862 | 7856 | if it is a potentially-evaluated explicit or implicit invocation of
|
7863 | 7857 | an immediate function and
|
7864 | 7858 | is not in an immediate function context.
|
7865 |
| -An immediate invocation shall be a constant expression. |
| 7859 | +An aggregate initialization is an immediate invocation |
| 7860 | +if it evaluates a default member initializer |
| 7861 | +that has a subexpression that is an immediate-escalating expression. |
| 7862 | + |
| 7863 | +\pnum |
| 7864 | +\indexdefn{expression!immediate-escalating}% |
| 7865 | +\indexdefn{conversion!immediate-escalating}% |
| 7866 | +\indexdefn{immediate-escalating!expression|see{expression, immediate-escalating}}% |
| 7867 | +\indexdefn{immediate-escalating!conversion|see{conversion, immediate-escalating}}% |
| 7868 | +An expression or conversion is \defn{immediate-escalating} |
| 7869 | +if it is not initially in an immediate function context |
| 7870 | +and it is either |
| 7871 | +\begin{itemize} |
| 7872 | +\item |
| 7873 | +a potentially-evaluated \grammarterm{id-expression} |
| 7874 | +that denotes an immediate function |
| 7875 | +that is not a subexpression of an immediate invocation, or |
| 7876 | +\item |
| 7877 | +an immediate invocation that is not a constant expression |
| 7878 | +and is not a subexpression of an immediate invocation. |
| 7879 | +\end{itemize} |
| 7880 | + |
| 7881 | +\pnum |
| 7882 | +\indexdefn{immediate-escalating!function|see{function, immediate-escalating}}% |
| 7883 | +An \defnx{immediate-escalating}{function!immediate-escalating} function is |
| 7884 | +\begin{itemize} |
| 7885 | +\item |
| 7886 | +the call operator of a lambda that is not declared |
| 7887 | +with the \keyword{consteval} specifier, |
| 7888 | +\item |
| 7889 | +a defaulted special member function |
| 7890 | +that is not declared with the \keyword{consteval} specifier, or |
| 7891 | +\item |
| 7892 | +a function that results from the instantiation |
| 7893 | +of a templated entity defined with the \keyword{constexpr} specifier. |
| 7894 | +\end{itemize} |
| 7895 | +An immediate-escalating expression shall appear only |
| 7896 | +in an immediate-escalating function. |
| 7897 | + |
| 7898 | +\pnum |
| 7899 | +An \defnadj{immediate}{function} is a function or constructor that is |
| 7900 | +\begin{itemize} |
| 7901 | +\item |
| 7902 | +declared with the \keyword{consteval} specifier, or |
| 7903 | +\item |
| 7904 | +an immediate-escalating function \tcode{\placeholder{F}} |
| 7905 | +whose function body contains an immediate-escalating expression \tcode{\placeholder{E}} |
| 7906 | +such that \tcode{\placeholder{E}}'s innermost enclosing non-block scope |
| 7907 | +is \tcode{\placeholder{F}}'s function parameter scope. |
| 7908 | +\end{itemize} |
| 7909 | +\begin{example} |
| 7910 | +\begin{codeblock} |
| 7911 | +consteval int id(int i) { return i; } |
| 7912 | +constexpr char id(char c) { return c; } |
| 7913 | + |
| 7914 | +template<class T> |
| 7915 | +constexpr int f(T t) { |
| 7916 | + return t + id(t); |
| 7917 | +} |
| 7918 | + |
| 7919 | +auto a = &f<char>; // OK, \tcode{f<char>} is not an immediate function |
| 7920 | +auto b = &f<int>; // error: \tcode{f<int>} is an immediate function |
| 7921 | + |
| 7922 | +static_assert(f(3) == 6); // OK |
| 7923 | + |
| 7924 | +template<class T> |
| 7925 | +constexpr int g(T t) { // \tcode{g<int>} is not an immediate function |
| 7926 | + return t + id(42); // because \tcode{id(42)} is already a constant |
| 7927 | +} |
| 7928 | + |
| 7929 | +template<class T, class F> |
| 7930 | +constexpr bool is_not(T t, F f) { |
| 7931 | + return not f(t); |
| 7932 | +} |
| 7933 | + |
| 7934 | +consteval bool is_even(int i) { return i % 2 == 0; } |
| 7935 | + |
| 7936 | +static_assert(is_not(5, is_even)); // OK |
| 7937 | + |
| 7938 | +int x = 0; |
| 7939 | + |
| 7940 | +template<class T> |
| 7941 | +constexpr T h(T t = id(x)) { // \tcode{h<int>} is not an immediate function |
| 7942 | + return t; |
| 7943 | +} |
| 7944 | + |
| 7945 | +template<class T> |
| 7946 | +constexpr T hh() { // \tcode{hh<int>} is an immediate function |
| 7947 | + return h<T>(); |
| 7948 | +} |
| 7949 | + |
| 7950 | +int i = hh<int>(); // error: ill-formed, \tcode{hh<int>()} is an immediate-escalating expression |
| 7951 | + // outside of an immediate-escalating function |
| 7952 | + |
| 7953 | +struct A { |
| 7954 | + int x; |
| 7955 | + int y = id(x); |
| 7956 | +}; |
| 7957 | + |
| 7958 | +template<class T> |
| 7959 | +constexpr int k(int) { // \tcode{k<int>} is not an immediate function because \tcode{A(42)} is a |
| 7960 | + return A(42).y; // constant expression and thus not immediate-escalating |
| 7961 | +} |
| 7962 | +\end{codeblock} |
| 7963 | +\end{example} |
| 7964 | + |
7866 | 7965 |
|
7867 | 7966 | \pnum
|
7868 | 7967 | An expression or conversion is \defn{manifestly constant-evaluated}
|
|
0 commit comments