Namespaces
Variants
Actions

User:Runge

From cppreference.com

C++ user and leaner.

Contents

Explanation of immediate-*

An immediate function F is either:

  • a function declared with consteval specifier, or
  • is escalated from a immediate-escalating function (see below) which contains (at least) an immediate-escalating expression (see below) immediately . To be precise, there's an immediate-escalating expression E inside F's function body such that E's innermost enclosing non-block scope is F's function parameter scope.

An expression or conversion is in an immediate function context if it is potentially-evaluated and either:

(since C++23)

An immediate-escalating function is a function that possibly be escalated to become an immediate function. It's either:

  • the call operator of a lambda that is not declared with the consteval specifier, or
  • a defaulted special member function that is not declared with the consteval specifier, or
  • a function that results from the instantiation of a templated entity defined with the constexpr specifier.

Roughly speaking, an immediate-escalating expression is a expression E which 1) needs to be evaluated in an immediate function context but initially not in, and 2) which is contained by a immediate-escalating function F. Hence, this makes F an immediate function (according to the second bullet of immediate function) and makes E in an immediate function context (according to the first bullet of immediate function context). Through this argument, consteval could propagate up, or in other word, such expression colors its enclosing (immediate-escalating) function consteval.

To be precise, a expression is an immediate-escalating expression if it is not initially in an immediate function context and it is either:

  • a potentially-evaluated id-expression that denotes an immediate function that is not a subexpression of an immediate invocation (see below), or
  • an immediate invocation (see below) that is not a constant expression and is not a subexpression of an immediate invocation.

Notably, if an invocation of an immediate function already has already formed a constant expression or inside an immediate invocation expression, then the id-expression of a immediate function in such invocation will not make it an immediate-escalating expression.

And an immediate-escalating expression shall appear only in an immediate-escalating function. Or in other word, it needs to be invoked inside an immediate function context, if it is unable to color its enclosing function with consteval through immediate-escalating mechanism, then such invocation results in a compile-time error.

An invocation is an immediate invocation if it is:

  • a potentially-evaluated explicit or implicit invocation of an immediate function and is not in an immediate function context, or
  • an aggregate initialization that evaluates a default member initializer with a subexpression that is an immediate-escalating expression.
consteval int id(int i) { return i; }   // immediate function
constexpr char id(char c) { return c; } // non immediate
 
template<class T>
constexpr int f(T t) { // its instantiation forms an immediate-escalating function
  return t + id(t);
}
 
auto a = &f<char>;
// OK, since char id(char) is not an immediate function, 
// there's no immediate invocation inside f's function body. 
// f<char> will not be escalated.          
// auto b = &f<int>;            
// error: f<int> is an immediate function since `id(t)` is now a
// immediate invocation due to now id references to an immediate function
// int id(int), then f<int> is escalated to be an immediate function.
 
static_assert(f(3) == 6);       
// OK, invocation of an immediate function inside 
// a manifestly constant evaluated context
 
template<class T>
constexpr int g(T t) {          // its instantiation forms an immediate-escalating function,
  return t + id(42);            // but g<int> is not an immediate function because 
}                               // id(42) is already a constant expression
 
template<class T, class F>
constexpr bool is_not(T t, F f) {  // its instantiation forms an immediate-escalating function
  return not f(t);
}
 
consteval bool is_even(int i) { return i % 2 == 0; } // immediate function
 
static_assert(is_not(5, is_even));      
// OK, is_even denote an immediate function and 
// is_not<int, bool(*)(int)> is escalated to be an immediate function
 
int x = 0;
 
template<class T>
constexpr T h(T t = id(x)) { // h<int> is not an immediate function
                             // id(x) is not evaluated when parsing the default argument ([dcl.fct.default], [temp.inst])
    return t;
}
 
template<class T>
constexpr T hh() { // hh<int> is an immediate function because of the invocation
  return h<T>();   // of the immediate function id in the default argument of h<int>
}
 
int i = hh<int>(); // error: hh<int>() is an immediate-escalating expression
                   // outside of an immediate-escalating function
 
struct A {
  int x;
  int y = id(x);
};
 
template<class T>
constexpr int k(int) { // k<int> is not an immediate function because A(42) is a
  return A(42).y;      // constant expression and thus not immediate-escalating
}

Immediate invocation

An invocation is an immediate invocation if it is:

  • a potentially-evaluated explicit or implicit invocation of an immediate function and is not in an immediate function context, or
  • an aggregate initialization that evaluates a default member initializer with a subexpression that is an immediate-escalating expression.

Immediate function

An immediate function is a function that is:

  • declared with the consteval specifier,or
  • an immediate-escalating function F whose function body contains an immediate-escalating expression E such that E's innermost enclosing non-block is F's function parameter scope.

Immediate function context

An expression or conversion is in an immediate function context if it is potentially-evaluated and either:

(since C++23)

Immediate-escalating function

An immediate-escalating function is:

  • the call operator of a lambda that is not declared with the consteval specifier, or
  • a defaulted special member function that is not declared with the consteval specifier, or
  • a function that results from the instantiation of a templated entity defined with the constexpr specifier.

Immediate-escalating expression

An expression or conversion is immediate-escalating if it is not initially in an immediate function context and it is either:

  • a potentially-evaluated id-expression that denotes an immediate function that is not a subexpression of an immediate invocation, or
  • an immediate invocation that is not a constant expression and is not a subexpression of an immediate invocation.

An immediate-escalating expression shall appear only in an immediate-escalating function.

Examples: TBD.