<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    CWG Issue 2603</TITLE>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<STYLE TYPE="text/css">
  INS { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  .INS { text-decoration:none; background-color:#D0FFD0 }
  DEL { text-decoration:line-through; background-color:#FFA0A0 }
  .DEL { text-decoration:line-through; background-color: #FFD0D0 }
  @media (prefers-color-scheme: dark) {
    HTML { background-color:#202020; color:#f0f0f0; }
    A { color:#5bc0ff; }
    A:visited { color:#c6a8ff; }
    A:hover, a:focus { color:#afd7ff; }
    INS { background-color:#033a16; color:#aff5b4; }
    .INS { background-color: #033a16; }
    DEL { background-color:#67060c; color:#ffdcd7; }
    .DEL { background-color:#67060c; }
  }
  SPAN.cmnt { font-family:Times; font-style:italic }
</STYLE>
</HEAD>
<BODY>
<P><EM>This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21
  Core Issues List revision 118b.
  See http://www.open-std.org/jtc1/sc22/wg21/ for the official
  list.</EM></P>
<P>2025-09-28</P>
<HR>
<A NAME="2603"></A><H4>2603.
  
Holistic functional equivalence for function templates
</H4>
<B>Section: </B>13.7.7.2&#160; [<A href="https://wg21.link/temp.over.link">temp.over.link</A>]
 &#160;&#160;&#160;

 <B>Status: </B>C++23
 &#160;&#160;&#160;

 <B>Submitter: </B>Davis Herring
 &#160;&#160;&#160;

 <B>Date: </B>2022-06-20<BR>


<P>[Accepted as a DR at the November, 2022 meeting.]</P>

<P>In C++20, 13.7.7.2 [<A href="https://wg21.link/temp.over.link#7">temp.over.link</A>] paragraph 7 defined
equivalence for function templates in terms of equivalence of several
of its components; functional equivalence for them was similar in that
it was defined recursively for their "return types and parameter
lists", but differed with regard to constraints in that it required
that they "accept and are satisfied by the same set of template
argument lists". P1787R6 simplified the treatment by relying entirely
on the "depends on whether two constructs are equivalent, and they are
functionally equivalent but not equivalent" rule to make the
correspondence check between the function templates ill-formed, no
diagnostic required.</P>

<P>This created a situation where moving a constraint between
a <I>template-head</I> and a <I>requires-clause</I> makes a function
template truly different (because there is no reasonable way to read
6.4.1 [<A href="https://wg21.link/basic.scope.scope#4.3.2">basic.scope.scope</A>] bullet 4.3.2's "equivalent
[...], <I>template-head</I>s, and <I>trailing requires-clause</I>s (if
any)" as requiring a <I>joint</I> check for functional equivalence),
even if overload resolution would never be able to distinguish
them.</P>

<P><U>Suggested resolution [SUPERSEDED]:</U></P>

<P>Change in 13.7.7.2 [<A href="https://wg21.link/temp.over.link#7">temp.over.link</A>] paragraph 7 as follows:</P>

<BLOCKQUOTE>

If the validity or meaning of the program depends on whether two
constructs are equivalent, and they are functionally equivalent but
not equivalent, the program is ill-formed, no diagnostic
required. <INS>Furthermore, if two function templates do not
correspond, but accept and are satisfied by the same set of template
argument lists, the program is ill-formed, no diagnostic
required.</INS>

</BLOCKQUOTE>

<P><U>Suggested resolution (August, 2022) [SUPERSEDED]:</U></P>

<OL>

<LI>

<P>Append to 6.4.1 [<A href="https://wg21.link/basic.scope.scope#3">basic.scope.scope</A>] paragraph 3 as follows:</P>

<P>
<UL>
<LI>...</LI>
<LI>the types of their object parameters are equivalent.</LI>
</UL>
<INS>Two function templates have <I>corresponding signatures</I> if
their <I>template-parameter-list</I>s have the same length,
corresponding <I>template-parameter</I>s are equivalent, they have
equivalent non-object-parameter-type-lists and return types (if any),
and, if both are non-static members, they have corresponding object
parameters.</INS>
</P>

</LI>

<LI>
<P>Change in 6.4.1 [<A href="https://wg21.link/basic.scope.scope#4">basic.scope.scope</A>] paragraph 4 as follows:</P>

<UL>
<LI>...</LI>
<LI>
<UL>
<LI>...</LI>
<LI>both declare function templates with <INS>corresponding signatures
and</INS> equivalent <DEL>non-object-parameter-type-lists, return
types (if any),</DEL> <I>template-head</I>s<DEL>,</DEL> and trailing
<I>requires-clause</I>s (if any)<DEL>, and, if both are non-static members,
they have corresponding object parameters</DEL>.
</LI>
</UL>
</LI>
</UL>

</LI>

<LI>

<P>Change in 13.7.7.2 [<A href="https://wg21.link/temp.over.link#7">temp.over.link</A>] paragraph 7 as follows:</P>

<BLOCKQUOTE>

If the validity or meaning of the program depends on whether two
constructs are equivalent, and they are functionally equivalent but
not equivalent, the program is ill-formed, no diagnostic
required. <INS>Furthermore, if two function templates with
corresponding signatures do not correspond, but accept and are
satisfied by the same set of template argument lists, the program is
ill-formed, no diagnostic required.</INS>

</BLOCKQUOTE>

</LI>

</OL>

<P><B>Proposed resolution (approved by CWG 2022-09-09):</B></P>

<OL>

<LI>

<P>Append to 6.4.1 [<A href="https://wg21.link/basic.scope.scope#3">basic.scope.scope</A>] paragraph 3 as follows:</P>

<P>
<UL>
<LI>...</LI>
<LI>the types of their object parameters are equivalent.</LI>
</UL>
<INS>Two function templates have <I>corresponding signatures</I> if
their <I>template-parameter-list</I>s have the same length,
corresponding <I>template-parameter</I>s are equivalent, they have
equivalent non-object-parameter-type-lists and return types (if any),
and, if both are non-static members, they have corresponding object
parameters.</INS>
</P>

</LI>

<LI>
<P>Change in 6.4.1 [<A href="https://wg21.link/basic.scope.scope#4">basic.scope.scope</A>] paragraph 4 as follows:</P>

<UL>
<LI>...</LI>
<LI>
<UL>
<LI>...</LI>
<LI>both declare function templates with <INS>corresponding signatures
and</INS> equivalent <DEL>non-object-parameter-type-lists, return
types (if any),</DEL> <I>template-head</I>s<DEL>,</DEL> and trailing
<I>requires-clause</I>s (if any)<DEL>, and, if both are non-static members,
they have corresponding object parameters</DEL>.
</LI>
</UL>
</LI>
</UL>

</LI>

<LI>

<P>Change in 13.7.7.2 [<A href="https://wg21.link/temp.over.link#7">temp.over.link</A>] paragraph 7 as follows:</P>

<BLOCKQUOTE>

If the validity or meaning of the program depends on whether two
constructs are equivalent, and they are functionally equivalent but
not equivalent, the program is ill-formed, no diagnostic
required.
<INS>Furthermore, if two function templates that do not correspond</INS>

<UL>
<LI><INS>have the same name,</INS></LI>
<LI><INS>have corresponding signatures (6.4.1 [<A href="https://wg21.link/basic.scope.scope">basic.scope.scope</A>]),</INS></LI>
<LI><INS>would declare the same entity
(6.7 [<A href="https://wg21.link/basic.link">basic.link</A>]) considering them to correspond, and</INS></LI>
<LI><INS>accept and are satisfied by the same set of template argument lists,</INS></LI>
</UL>
<INS>the program is ill-formed, no diagnostic required.</INS>

</BLOCKQUOTE>

</LI>

</OL>

<BR><BR>
</BODY>
</HTML>
