<html>
<head>
<title>P1972R0: US105 Check satisfaction of constraints for non-templates when forming pointer to function</title>

<style type="text/css">
  ins { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  del { text-decoration:line-through; background-color:#FFA0A0 }
  strong { font-weight: inherit; color: #2020ff }
  #xins:checked ~ * ins { display:none; visibility:hidden }
  #xdel:checked ~ * del { display:none; visibility:hidden }
</style>

</head>

<body>
<p>
Jens Maurer<br>
2019-11-07
</p>

<input type="checkbox" id="xins"/><label for="xins">Hide inserted text</label>
<input type="checkbox" id="xdel"/><label for="xdel">Hide deleted text</label>

<h1>P1972R0: US105 Check satisfaction of constraints for non-templates when forming pointer to function</h1>


This paper presents the wording changes for the NB comment US105 on
the C++20 CD.
<p>

Do not change [dcl.fct.def.delete] paragraph 2.

<p>
Change 7.3.3 [conv.func]:

<blockquote>
An lvalue of function type T can be converted to a prvalue of type
“pointer to T”. The result is a pointer to the function. [ Footnote: ... ]

<p>
<del>[Note: See 12.5 for additional rules for the case where the
function is overloaded. — end note]</del>

</blockquote>

Change in 7.5.4 [expr.prim.id] paragraph 5:

<blockquote>
<ins>For an <em>id-expression</em> that denotes an overload
set, overload resolution is performed to select a unique function
(12.4 [over.match], 12.5 [over.over]).</ins>
<del>A program that refers explicitly or implicitly to a function with a trailing requires-clause whose constraint-
  expression is not satisfied, other than to declare it, is ill-formed.</del>
<ins>[ Note: A program cannot refer to a function with a trailing <em>requires-clause</em> whose <em>constraint-expression</em> is not satisfied, because such functions are never selected by overload resolution.</ins>
[Example:
<pre>
  void f(int) requires false;
  void g() {
    f(0);                              // error: cannot call f
    void (*p1)(int) = f;               // error: cannot take the address of f
    decltype(f)* p2 = nullptr;         // error: the type decltype(f) is invalid
  }
</pre>
In each case, the constraints of f are not satisfied. In the declaration of p2, those constraints are required to
be satisfied even though f is an unevaluated operand (7.2). — end example] <ins>-- end note ]</ins>

</blockquote>

Change in 7.6.1.2 [expr.call] paragraphs 1 and 3:

<blockquote>
A function call is a postfix expression followed by parentheses
containing a possibly empty, comma-separated list of
initializer-clauses which constitute the arguments to the
function.
<ins>[ Note: If the postfix expression is a function or member
function name, the appropriate function and the validity of the call
are determined according to the rules in 12.4 [over.match].  -- end
note ]</ins> The postfix expression shall have function type or
function pointer type. For a call to a non-member function or to a
static member function, the postfix expression shall either be an
lvalue that refers to a function (in which case the
function-to-pointer standard conversion (7.3.3) is suppressed on the
postfix expression), or have function pointer type.
<p>
  ...
<p>

<del>If a function or member function name is used, the appropriate
function and the validity of the call are determined according to the
rules in 12.4.</del> If the selected function is non-virtual, or if the
id-expression in the class member access expression is a qualified-id,
that function is called. Otherwise, its final overrider (11.7.2) ...
</blockquote>

Change in 7.6.2.1 [expr.unary.op] paragraph 6:

<blockquote>
<ins>[ Note:</ins>
The address of an overloaded function (Clause 12) can be taken only in
a context that uniquely determines which version of the overloaded
function is referred to (see 12.5). <del>[Note:</del> Since the context might
determine whether the operand is a static or non-static member
function, the context can also affect whether the expression has type
“pointer to function” or “pointer to member function”. — end note]

</blockquote>

Change in 12.5 [over.over] paragraph 1:

<blockquote>
A use of <del>an overloaded</del> <ins>a</ins> function name without
arguments is resolved <del>in certain contexts</del> to a function, a pointer to
function or a pointer to member function for a specific function from
<ins>a set of selected functions, as described below</ins> <del>the overload set. A function template name is considered to name a set
of overloaded functions in such contexts</del>. A function with type F is
selected for the function type FT of the target type required in the
context if F (after possibly applying the function pointer conversion
(7.3.13)) is identical to FT. [Note: That is, the class of which the
function is a member is ignored when matching a
pointer-to-member-function type. — end note] The target can be
<ul>
  <li>...</li>
</ul>
<ins>If there is no target, all functions named are selected.</ins>
The <del>overloaded</del> function name can be preceded by the & operator. <del>An overloaded function name shall not
be used without arguments in contexts other than those listed.</del> [Note: Any redundant set of parentheses
surrounding the <del>overloaded</del> function name is ignored (7.5.3). — end note]
</blockquote>

Change in 12.5 [over.over] paragraph 2:

<blockquote>
<ins>For each function template designated by the name,</ins>
<del>If the name is a function template,</del>
template argument deduction is
done (13.10.2.2), and if the argument deduction succeeds, the
resulting template argument list is used to generate a single function
template specialization, which is added to the set <ins>of selected functions</ins>
<del>of overloaded functions</del> considered. [Note: As described in 13.10.1, if deduction
fails and the function template name is followed by an explicit
template argument list, the template-id is then examined to see
whether it identifies a single function template specialization. If it
does, the template-id is considered to be an lvalue for that function
template specialization. The target type is not used in that
determination. — end note]

</blockquote>

Change 13.10.2.2 [temp.deduct.funcaddr]:

<blockquote>
Template arguments can be deduced from the type specified when taking the address of an overloaded
function (12.5). <ins>If there is a target, the</ins> <del>The</del> function template’s function type and the <del>specified</del> <ins>target</ins> type are used as the types of P and
A, and the deduction is done as described in 13.10.2.5.  <ins>Otherwise,
deduction is performed with empty sets of types P and A.</ins>
<p>
A placeholder type (9.2.8.5) in the return type of a function template
is a non-deduced context. If template argument deduction succeeds for
such a function, the return type is determined from instantiation of
the function body.

</blockquote>

</body>
</html>
