| Document #: | P4176R0 [Latest] [Status] |
| Date: | 2026-04-20 |
| Project: | Programming Language C++ |
| Audience: |
Core Working Group |
| Reply-to: |
Vlad Serebrennikov <serebrennikov.vladislav@gmail.com> |
7.6.1 [expr.post] lists all the grammar at the top, while the rest of the subclause resorts to either quoting the grammar or describing it with words. This paper aims to improve the situation, introducing new nonterminals and putting their definitions in the respective subclauses.
R0:
No changes to behavior of programs are intended.
Change 7.6.1.1 [expr.post.general] paragraph 1 as follows:
1 Postfix expressions group left-to-right.
postfix-expression:primary-expressionpostfix-expression[expression-listopt]subscript-expressionpostfix-expression(expression-listopt)function-call-expressionsimple-type-specifier(expression-listopt)
typename-specifier(expression-listopt)
simple-type-specifier braced-init-list
typename-specifier braced-init-listtype-conversion-expressionpostfix-expression.templateopt id-expression
postfix-expression.splice-expression
postfix-expression->templateopt id-expression
postfix-expression->splice-expressionclass-member-access-expressionpostfix-expression++post-increment-expressionpostfix-expression--post-decrement-expressiondynamic_cast<type-id>(expression)dynamic-cast-expressionstatic_cast<type-id>(expression)static-cast-expressionreinterpret_cast<type-id>(expression)reinterpret-cast-expressionconst_cast<type-id>(expression)const-cast-expressiontypeid(expression)
typeid(type-id)typeid-expressionexpression-list:initializer-list
Remove 7.6.1.1 [expr.post.general] paragraph 2:
[Note: The
>token following the type-id in adynamic_cast,static_cast,reinterpret_cast, orconst_castcan be the product of replacing a>>token by two consecutive>tokens (13.3 [temp.names]). — end note ]
[ Drafting note: A similar note is added to each kind of cast. ]
Change 7.6.1.2 [expr.sub] paragraph 1 as follows:
1 A subscript expression is a
postfix expression followed by square brackets containing a possibly empty, comma-separated list of initializer-clauses thatsubscript-expression, which has the following formsubscript-expression:postfix-expression[expression-listopt]The expression-list constitutes the arguments to the subscript operator. The postfix-expression and the initialization of the object parameter (9.3.4.6 [dcl.fct]) of any applicable subscript operator function (12.4.5 [over.sub]) is sequenced before each expression in the expression-list and also before any default argument (9.3.4.7 [dcl.fct.default]). The initialization of a non-object parameter of a subscript operator function
S, including every associated value computation and side effect, is indeterminately sequenced with respect to that of any other non-object parameter ofS.
Change 7.6.1.3 [expr.call] paragraph 1 as follows:
1 A
function callfunction call is apostfix expression followed by parentheses containing a possibly empty, comma-separated list of initializer-clauses whichfunction-call-expression, which has the formfunction-call-expression:postfix-expression(expression-listopt)The expression-list, if present, constitutes the arguments to the function.
[Note: If the
postfix expressionpostfix-expression is a function name, the appropriate function and the validity of the call are determined according to the rules in 12.2 [over.match]. — end note ]The
postfix expressionpostfix-expression E shall have function type or function pointer type. For a call to a non-member function or to a static member function,the postfix expressionE shall be either an lvalue that refers to a function (in which case the function-to-pointer standard conversion (7.3.4 [conv.func]) is suppressed onthe postfix expressionE), or a prvalue of function pointer type.
Change 7.6.1.3 [expr.call] paragraph 2 as follows:
2 If the selected function is non-virtual, or if the id-expression in the
class member access expressionclass-member-access-expression is a qualified-id, that function is called. Otherwise, its final overrider (11.7.3 [class.virtual]) in the dynamic type of the object expression is called; such a call is referred to as a virtual function call.[Note: [. . .] — end note ]
Change 7.6.1.4 [expr.type.conv] paragraph 1 as follows:
type-conversion-expression:simple-type-specifier(expression-listopt)
typename-specifier(expression-listopt)
simple-type-specifier braced-init-list
typename-specifier braced-init-list1
A simple-type-specifier or typename-specifier followed by a parenthesized optional expression-list or by a braced-init-list (the initializer)A type-conversion-expression constructs a value of thespecifiedtype specified by simple-type-specifier or typename-specifier given the initializer, which is braced-init-list or parentheses containing optional expression-list. If the type is a placeholder for a deduced class type, it is replaced by the return type of the function selected by overload resolution for class template deduction for the remainder of this subclause. Otherwise, if the type contains a placeholder type, it is replaced by the type determined by placeholder type deduction (9.2.9.7.2 [dcl.type.auto.deduct]). LetTdenote the resulting type. Then:
- (1.1) If the initializer is a parenthesized
single expressionexpression-list with a single initializer-clause, the type conversion expression is equivalent to the corresponding cast expression (7.6.3 [expr.cast]).- (1.2) Otherwise, if
Tis cvvoid, the initializer shall be()or{}(after pack expansion, if any), and the expression is a prvalue of typevoidthat performs no initialization.- (1.3) Otherwise, if
Tis a reference type, the expression has the same effect as direct-initializing an invented variabletof typeTfrom the initializer and then usingtas the result of the expression; the result is an lvalue ifTis an lvalue reference type or an rvalue reference to function type and an xvalue otherwise.- (1.4) Otherwise, the expression is a prvalue of type
Twhose result object is direct-initialized (9.5 [dcl.init]) with the initializer.If the initializer is a parenthesized optional expression-list,
Tshall not be an array type.[Example: [. . .] — end example ]
Change 7.6.1.5 [expr.ref] paragraph 1 as follows:
1 A class member access expression is a class-member-access-expression, which has one of the following forms
class-member-access-expression:postfix-expression.templateopt id-expression
postfix-expression.splice-expression
postfix-expression->templateopt id-expression
postfix-expression->splice-expression
A postfix expression followed by a dot.or an arrow->, optionally followed by the keywordtemplate, and then followed by an id-expression or a splice-expression, is a postfix expression.[Note: If the keyword
templateis used and followed by an id-expression, the unqualified name is considered to refer to a template (13.3 [temp.names]). If a simple-template-id results and is followed by a::, the id-expression is a qualified-id. — end note ]
Change footnote 45 referenced from 7.6.1.5 [expr.ref] paragraph 3:
If the
class member access expressionclass-member-access-expression is evaluated, the subexpression evaluation happens even if the result is unnecessary to determine the value of the entire postfix expression, for example if the id-expression denotes a static member.
Apply the following changes to the entire subclause 7.6.1.6 [expr.post.incr]:
post-increment-expressionpostfix-expression++post-decrement-expressionpostfix-expression--1 The value of
a postfixa post-increment-expression is the value obtained by applying the lvalue-to-rvalue conversion (7.3.2 [conv.lval]) to its operand, which is the postfix-expression.++expression[Note: The value obtained is a copy of the original value. — end note ]
The operand shall be a modifiable lvalue. The type of the operand shall be an arithmetic type other than cv
bool, or a pointer to a complete object type. An operand with volatile-qualified type is deprecated; see D.4 [depr.volatile.type]. The value of the operand object is modified (3.1 [defns.access]) as if it were the operand of the prefix++operator (7.6.2.3 [expr.pre.incr]). The value computation of the++expression is sequenced before the modification of the operand object. With respect to an indeterminately-sequenced function call, the operation of postfix++is a single evaluation.[Note: Therefore, a function call cannot intervene between the lvalue-to-rvalue conversion and the side effect associated with any single postfix
++operator. — end note ]The result is a prvalue. The type of the result is the cv-unqualified version of the type of the operand.
2 The operand of
postfixpost-decrement-expression is decremented analogously to the--postfixpost-increment-expression.++operator[Note: For prefix increment and decrement, see 7.6.2.3 [expr.pre.incr]. — end note ]
Change 7.6.1.7 [expr.dynamic.cast] paragraph 1 as follows:
dynamic-cast-expression:dynamic_cast<type-id>(expression)1
The result of the expressionThe result of a dynamic-cast-expression is the result of converting the expressiondynamic_cast<T>(v)is the result of converting the expressionvto typeT.vto the typeTdesignated by the type-id.Tshall be a pointer or reference to a complete class type, or “pointer to cvvoid”. Thedynamic_castoperator shall not cast away constness (7.6.1.11 [expr.const.cast]).[Note: The
>token following the type-id can be the product of replacing a>>token by two consecutive>tokens (13.3 [temp.names]). — end note ]
Change 7.6.1.8 [expr.typeid] paragraph 1 as follows:
typeid-expressiontypeid(expression)
typeid(type-id)1 The result of a
typeid-expression is an lvalue of static typetypeidexpressionconst std::type_info(17.7.3 [type.info]) and dynamic typeconst std::type_infoorconstname where name is an implementation-defined class publicly derived fromstd::type_infowhich preserves the behavior described in 17.7.3 [type.info].48 The lifetime of the object referred to by the lvalue extends to the end of the program. Whether or not the destructor is called for thestd::type_infoobject at the end of the program is unspecified.
Change 7.6.1.9 [expr.static.cast] paragraph 1 as follows:
static-cast-expression
static_cast<type-id>(expression)1
The result of the expressionThe result of a static-cast-expression is the result of converting the expressionstatic_cast<T>(v)is the result of converting the expressionvto typeT.vto the typeTdesignated by the type-id. IfTis an lvalue reference type or an rvalue reference to function type, the result is an lvalue; ifTis an rvalue reference to object type, the result is an xvalue; otherwise, the result is a prvalue.[Note: The
>token following the type-id can be the product of replacing a>>token by two consecutive>tokens (13.3 [temp.names]). — end note ]
Change 7.6.1.10 [expr.reinterpret.cast] paragraph 1 as follows:
reinterpret-cast-expressionreinterpret_cast<type-id>(expression)1
The result of the expressionThe result of a reinterpret-cast-expression is the result of converting the expressionreinterpret_cast<T>(v)is the result of converting the expressionvto typeT.vto the typeTdesignated by the type-id. IfTis an lvalue reference type or an rvalue reference to function type, the result is an lvalue; ifTis an rvalue reference to object type, the result is an xvalue; otherwise, the result is a prvalue and the lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard conversions are performed on the expressionv. Conversions that can be performed explicitly usingreinterpret_castare listed below. No other conversion can be performed explicitly usingreinterpret_cast.[Note: The
>token following the type-id can be the product of replacing a>>token by two consecutive>tokens (13.3 [temp.names]). — end note ]
Change 7.6.1.11 [expr.const.cast] paragraph 1 as follows:
const-cast-expressionconst_cast<type-id>(expression)1
The result of theThe result of a const-cast-expression is the result of converting the expressionconst_cast<T>(v)is of typeT.vto the typeTdesignated by the type-id. IfTis an lvalue reference to object type, the result is an lvalue; ifTis an rvalue reference to object type, the result is an xvalue; otherwise, the result is a prvalue and the lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard conversions are performed on the expressionv. The temporary materialization conversion is not performed onv, other than as specified below. Conversions that can be performed explicitly usingconst_castare listed below. No other conversion shall be performed explicitly usingconst_cast.[Note: The
>token following the type-id can be the product of replacing a>>token by two consecutive>tokens (13.3 [temp.names]). — end note ]
Change 12.2.2.2.1 [over.match.call.general] paragraph 1 as follows:
1 In a function call (7.6.1.3 [expr.call])
postfix-expression(expression-listopt)
ifIf the postfix-expression of a function-call-expression names at least one function or function template, overload resolution is applied as specified in 12.2.2.2.2 [over.call.func]. If the postfix-expression denotes an object of class type, overload resolution is applied as specified in 12.2.2.2.3 [over.call.object].
Apply the following changes to the entire subclause 12.2.2.2.2 [over.call.func]:
1 Of interest in 12.2.2.2.2 [over.call.func] are only those function calls in which the postfix-expression ultimately contains an id-expression or splice-expression that designates one or more functions. Such a postfix-expression, perhaps nested arbitrarily deep in parentheses, has one of the following forms:
postfix-expression:postfix-expression.id-expression
postfix-expression.splice-expression
postfix-expression->id-expression
postfix-expression->splice-expression
id-expression
splice-expressionThese represent two syntactic subcategories of function calls: qualified function calls and unqualified function calls.
2 Qualified function call is a function-call-expression whose postfix-expression, perhaps nested arbitrarily deep in parentheses, has one of the following forms:
postfix-expression.id-expression
postfix-expression.splice-expression
postfix-expression->id-expression
postfix-expression->splice-expressionIn
qualified functionsuch calls, the function is designated by an id-expression or splice-expression Epreceded by an. Since the construct->or.operatorA->Bis generally equivalent to(*A).B, the rest of Clause 12 [over] assumes, without loss of generality, that all member function calls have been normalized to the form that uses an object and the.operator. Furthermore, Clause 12 [over] assumes that the postfix-expression that is the left operand of the.operator has type “cvT” whereTdenotes a class.94 The set of candidate functions either is the set found by name lookup (6.5.2 [class.member.lookup]) if E is an id-expression or is the set determined as specified in 7.5.9 [expr.prim.splice] if E is a splice-expression. The argument listis the expression-list in the callconsists of the arguments of the function-call-expression augmented by the addition of the left operand of the.operator in the normalized member function call as the implied object argument (12.2.2 [over.match.funcs]).3 Unqualified function call is a function-call-expression whose postfix-expression, perhaps nested arbitrarily deep in parentheses, has one of the following forms:
id-expression
splice-expressionIn
unqualified functionsuch calls, the function is designated by an id-expression or a splice-expression E. The set of candidate functions either is the set found by name lookup (6.5 [basic.lookup]) if E is an id-expression or is the set determined as specified in 7.5.9 [expr.prim.splice] if E is a splice-expression. The set of candidate functions consists either entirely of non-member functions or entirely of member functions of some classT. In the former case or if E is either a splice-expression or the address of an overload set, the argument listis the same as the expression-list in the callconsists of the arguments of the function-call-expression. Otherwise, the argument listis the expression-list in the callconsists of the arguments of the function-call-expression augmented by the addition of an implied object argument as in a qualified function call. [. . .][Example: [. . .] — end example ]
Change 12.2.2.2.3 [over.call.object] paragraph 1 as follows:
1 If the postfix-expression E
in the function call syntaxof a function-call-expression evaluates to a class object of type “cvT”, then the set of candidate functions includes at least the function call operators ofT. The function call operators ofTare the results of a search for the nameoperator()in the scope ofT.
Change 12.4.4 [over.call] paragraph 1 as follows:
1 A function call operator function is a function named
operator()that is a member function with an arbitrary number of parameters. It may have default arguments. Foran expression of the forma function-call-expressionpostfix-expression(expression-listopt)where the postfix-expression is of class type, the operator function is selected by overload resolution (12.2.2.2.3 [over.call.object]). If a surrogate call function is selected, let e be the result of invoking the corresponding conversion operator function on the postfix-expression;
the expression is interpreted as
e(expression-listopt)Otherwise, the expression is interpreted as
postfix-expression.operator ()(expression-listopt)
Change 12.4.5 [over.sub] paragraph 1 as follows:
1 A subscripting operator function is a member function named
operator[]with an arbitrary number of parameters. It may have default arguments. Foran expression of the forma subscript-expressionpostfix-expression[expression-listopt]the operator function is selected by overload resolution (12.2.2.3 [over.match.oper]). If a member function is selected, the expression is interpreted as
postfix-expression.operator[](expression-listopt)
Change 12.4.6 [over.ref] paragraph 1 as follows:
1 A class member access operator function is a function named
operator->that is a non-static member function taking no non-object parameters. Foran expressiona class-member-access-expression of the formpostfix-expression->templateopt id-expressionthe operator function is selected by overload resolution (12.2.2.3 [over.match.oper]), and the expression is interpreted as
(postfix-expression.operator->())->templateopt id-expressionAnalogously, for
an expressiona class-member-access-expression of the formpostfix-expression->splice-expressionthe operator function is selected by overload resolution, and the expression is interpreted as
(postfix-expression.operator->())->splice-expression
Change 6.3 [basic.def.odr] paragraph 3 as follows:
3 An expression or conversion is potentially evaluated unless it is an unevaluated operand (7.2.3 [expr.context]), a subexpression thereof, or a conversion in an initialization or conversion sequence in such a context. The set of potential results of an expression E is defined as follows:
- [. . .]
- (3.3) If E is a
class member access expression (7.6.1.5)class-member-access-expression of the form E1.templateopt E2, where E2 designates a non-static data member or a direct base class relationship, the set contains the potential results of E1.- (3.4) If E is a
class member access expressionclass-member-access-expression naming a static data member, the set contains the id-expression designating the data member.- [. . .]
Change 6.5.3 [basic.lookup.unqual] paragraph 4 as follows:
4 An unqualified name is a name that does not immediately follow a nested-name-specifier or the
.or->in aclass member access expression (7.6.1.5)class-member-access-expression, possibly after atemplatekeyword or~. Unless otherwise specified, such a name undergoes unqualified name lookup from the point where it appears.
Change 6.5.4 [basic.lookup.argdep] paragraph 1 as follows:
1 When the postfix-expression in a
function call (7.6.1.3 [expr.call])function-call-expression is an unqualified-id, and unqualified lookup (6.5.3 [basic.lookup.unqual]) for the name in the unqualified-id does not find any
- (1.1) declaration of a class member, or
- (1.2) function declaration inhabiting a block scope, or
- (1.3) declaration not of a function or function template
then lookup for the name also includes the result of argument-dependent lookup in a set of associated namespaces that depends on the types of the arguments (and for type template template arguments, the namespace of the template argument), as specified below.
[Example: [. . .] — end example ]
Change 6.5.4 [basic.lookup.argdep] paragraph 2 as follows:
[Note: For purposes of determining (during parsing) whether an expression is a postfix-expression
for a function callof a function-call-expression, the usual name lookup rules apply. In some cases a name followed by<is treated as a template-name even though name lookup did not find a template-name (see 13.3 [temp.names]). For example,int h; void g(); namespace N { struct A {}; template <class T> int f(T); template <class T> int g(T); template <class T> int h(T); } int x = f<N::A>(N::A()); // OK, lookup offfinds nothing,ftreated as template name int y = g<N::A>(N::A()); // OK, lookup ofgfinds a function,gtreated as template name int z = h<N::A>(N::A()); // error:h<does not begin a template-idThe rules have no effect on the syntactic interpretation of an expression. For example,
typedef int f; namespace N { struct A { friend void f(A &); operator int(); void g(A a) { int i = f(a); //fis the typedef, not the friend function: equivalent toint(a)} }; }Because the expression is not a
function callfunction-call-expression, argument-dependent name lookup does not apply and the friend functionfis not found. — end note ]
Change 6.5.5.1 [basic.lookup.qual.general] paragraph 2 as follows:
2 A member-qualified name is the (unique) component name (7.5.5.2 [expr.prim.id.unqual]), if any, of
- (2.1) an unqualified-id or
- (2.2) a nested-name-specifier of the form type-name
::or namespace-name::in the id-expression of a
class member access expression (7.6.1.5 [expr.ref])class-member-access-expression. [. . .][Note: [. . .] — end note ]
[Example: [. . .] — end example ]
Change 6.8.6.5.1 [basic.stc.dynamic.general] paragraph 2 as follows:
2 [. . .]
[Note: he implicit declarations do not introduce the names
std,std::size_t,std::align_val_t, or any other names that the library uses to declare these names. Thus, a new-expression, delete-expression, orfunction callfunction-call-expression that refers to one of these functions without importing or including the header<new>(17.6.2 [new.syn]) or importing a C++ library module (16.4.2.4 [std.modules]) is well-formed. However, referring tostdorstd::size_torstd::align_val_tis ill-formed unless a standard library declaration (17.2.1 [cstddef.syn], 17.6.2 [new.syn], 16.4.2.4 [std.modules]) of that name precedes (6.5.1 [basic.lookup.general]) the use of that name. — end note ][. . .]
Change 6.10.1 [intro.execution] paragraph 11 as follows:
11 When invoking a function f (whether or not the function is inline), every argument expression and the
postfix expressionpostfix-expression designating f are sequenced before every precondition assertion of f (9.4.1 [dcl.contract.func]), which in turn are sequenced before every expression or statement in the body of f, which in turn are sequenced before every postcondition assertion of f.
Change 7.5.5.1 [expr.prim.id.general] paragraph 2 as folows:
2 If an id-expression E denotes a non-static non-type member of some class
Cat a point where the current class (7.5.3 [expr.prim.this]) isXand
- (2.1) E is potentially evaluated or
CisXor a base class ofX, and- (2.2) E is not the id-expression of a
class member access expression (7.6.1.5 [expr.ref])class-member-access-expression, and- (2.3) E is not the id-expression of a reflect-expression (7.6.2.10 [expr.reflect]), and
- (2.4) if E is a qualified-id, E is not the un-parenthesized operand of the unary
&operator (7.6.2.2 [expr.unary.op]),the id-expression is transformed into a class member access expression using
(*this)as the object expression. If this transformation occurs in the predicate of a precondition assertion of a constructor ofXor a postcondition assertion of a destructor ofX, the expression is ill-formed.[Note: If
Cis notXor a base class ofX, the class member access expression is ill-formed. Also, if the id-expression occurs within a static or explicit object member function, the class member access is ill-formed. — end note ]This transformation does not apply in the template definition context (13.8.3.2 [temp.dep.type]).
[Example: [. . .] — end example ]
Change 7.5.5.5 [expr.prim.id.dtor] paragraph 2 as follows:
2 If the id-expression names a pseudo-destructor,
Tshall be a scalar type and the id-expression shall appear as the right operand of aclass member access (7.6.1.5 [expr.ref])class-member-access-expression that forms the postfix-expression of afunction call (7.6.1.3 [expr.call])function-call-expression.
Change 7.5.9 [expr.prim.splice] paragraph 4 as follows:
4 For a splice-expression of the form template splice-specialization-specifier, the splice-specifier of the splice-specialization-specifier shall designate a template T.
- [. . .]
[Note: Class members are accessible from any point when designated by splice-expressions (11.8.3 [class.access.base]). A
class member access expression (7.6.1.5)class-member-access-expression whose right operand is a splice-expression is ill-formed if the left operand (considered as a pointer) cannot be implicitly converted to a pointer to the designating class of the right operand. — end note ]
Change 7.6.20 [expr.comma] paragraph 2 as follows:
[Note: In contexts where the comma token is given special meaning (e.g.,
function calls (7.6.1.3)function-call-expressions,subscript expressions (7.6.1.2)subscript-expressions,lists of initializers (9.5)initialzer-lists, or template-argument-lists (13.3 [temp.names])), the comma operator as described in this subclause can appear only in parentheses.— end note ][Example: [. . .] — end example ]
Change [expr.const.core] paragraph 2 as follows:
2 An expression E is a core constant expression unless the evaluation of E, following the rules of the abstract machine (6.10.1 [intro.execution]), would evaluate one of the following:
- (2.1)
this(7.5.3 [expr.prim.this]), except
- [. . .]
- (2.1.2) when appearing as the postfix-expression of an implicit or explicit
class member access expression (7.6.1.5 [expr.ref])class-member-access-expression;- [. . .]
- [. . .]
- (2.18) an invocation of a destructor (11.4.7 [class.dtor]) or a
function callfunction-call-expression whose postfix-expression names a pseudo-destructor (7.6.1.3 [expr.call]), in either case for an object whose lifetime did not begin within the evaluation of E;- [. . .]
Change 9.3.4.7 [dcl.fct.default] paragraph 9 as follows:
9 A default argument is evaluated each time the function is called with no argument for the corresponding parameter. A parameter shall not appear as a potentially evaluated expression in a default argument.
[Note: [. . .] — end note ]
[Example: [. . .] — end example ]
A non-static member shall not be designated in a default argument unless
- (9.1) it is designated by the id-expression or splice-expression of a
class member access expression (7.6.1.5)class-member-access-expression,- [. . .]
[. . .]
Change 13.8.3.1 [temp.dep.general] paragraph 2 as follows:
2 A
dependent calldependent call isan expressiona function-call-expression, possibly formed as a non-member candidate for an operator (12.2.2.3 [over.match.oper]),of the form:postfix-expression(expression-listopt)
where thewhose postfix-expression is an unqualified-id and
- (2.1) any of the expressions in the expression-list is a pack expansion (13.7.4 [temp.variadic]), or
- (2.2) any of the expression or brace-init-lists in the expression-list is type-dependent (13.8.3.3 [temp.dep.expr]), or
- (2.3) the unqualified-id is a template-id in which any of the template arguments depends on a template parameters.
The component name of an unqualified-id (7.5.5.2 [expr.prim.id.unqual]) is dependent if
- (2.4) it is a conversion-function-id whose conversion-type-id is dependent, or
- (2.5) it is
operator=and the current class is a templated entity, or- (2.6) the unqualified-id is the postfix-expression in a dependent call.
[Note: [. . .] — end note ]
Do not change 13.8.3.3 [temp.dep.expr] paragraph 3.
Change 13.8.3.3 [temp.dep.expr] paragraph 4 as follows:
4 Expressions of the following forms are never type-dependent (because the type of the expression cannot be dependent):
literal
sizeofunary-expression
sizeof(type-id)
sizeof...(identifier)
alignof(type-id)
typeid(expression)
typeid(type-id)
typeid-expression
::optdeletecast-expression
::optdelete[]cast-expression
throwassignment-expressionopt
noexcept(expression)
requires-expression
reflect-expression[Note: For the standard library macro
offsetof, see 17.2 [support.types]. — end note ]
Do not change 13.8.3.4 [temp.dep.constexpr] paragraphs 2 and 3.
Change 13.10.3.6 [temp.deduct.type] paragraph 23 as follows:
23 The template-argument corresponding to a template template parameter is deduced from the type of the template-argument of a class template specialization used in the argument list of a function call (12.2.2.2.2 [over.call.func]).
[Example: [. . .] — end example ]
Change 14.5 [except.spec] paragraph 5 as follows:
5 An expression E is potentially-throwing if
- (5.1) E is a
function call (7.6.1.3 [expr.call])function-call-expression whose postfix-expression has a function type, or a pointer-to-function type, with a potentially-throwing exception specification, or- [. . .]
Change 16.3.3.4 [alg.func.obj] paragraph 2 as follows:
2 For an algorithm function object
o, let S be the corresponding set of function templates. Then for any sequence of argumentsargs . . .,o(args . . . )is expression-equivalent tos(args . . . ), where the result of name lookup forsis the overload set S.[Note: Algorithm function objects are not found by argument-dependent name lookup (6.5.4 [basic.lookup.argdep]). When found by unqualified name lookup (6.5.3 [basic.lookup.unqual]) for the postfix-expression in a
function call (7.6.1.3 [expr.call])function-call-expression, they inhibit argument-dependent name lookup.[Example:— end note ]void foo() { using namespace std::ranges; std::vector<int> vec{1,2,3}; find(begin(vec), end(vec), 2); // #1 }The
function call expressionfunction-call-expression at #1 invokesstd::ranges::find, notstd::find. — end example ]
Change 17.8.2.2 [support.srcloc.cons] paragraph 1 as follows:
static consteval source_location current() noexcept;1 Returns:
- (1.1) When invoked by a
function callfunction-call-expression whose postfix-expression is a (possibly parenthesized) id-expression namingcurrent, returns asource_locationwith an implementation-defined value. [. . .]- [. . .]
Change 22.10.1 [function.objects.general] paragraph 1 as follows:
1 A function object type is an object type (6.9.1 [basic.types.general]) that can be the type of the postfix-expression in a
function call (7.6.1.3 [expr.call], 12.2.2.2 [over.match.call])function-call-expression.174