<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    CWG Issue 1321</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="1321"></A><H4>1321.
  
Equivalency of dependent calls
</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>CD3
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2011-05-18<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>Consider the following example:</P>

<PRE>
  int g(int);

  template &lt;class T&gt; decltype(g(T())) f();

  int g();

  template &lt;class T&gt; decltype(g(T())) f() { return g(T()); }

  int i = f&lt;int&gt;();
</PRE>

<P>Do the two <TT>f</TT>s declare the same function template?  According
to 13.7.7.2 [<A href="https://wg21.link/temp.over.link#5">temp.over.link</A>] paragraph 5,</P>

<BLOCKQUOTE>

Two expressions involving template parameters are considered
<I>equivalent</I> if two function definitions containing the expressions
would satisfy the one definition rule (6.3 [<A href="https://wg21.link/basic.def.odr">basic.def.odr</A>]),
except that the tokens used to name the template parameters may differ
as long as a token used to name a template parameter in one expression
is replaced by another token that names the same template parameter in
the other expression.

</BLOCKQUOTE>

<P>The relevant portion of 6.3 [<A href="https://wg21.link/basic.def.odr#5">basic.def.odr</A>] paragraph 5 says,</P>

<BLOCKQUOTE>

in each definition of <TT>D</TT>, corresponding names, looked up
according to 6.5 [<A href="https://wg21.link/basic.lookup">basic.lookup</A>], shall refer to an entity
defined within the definition of <TT>D</TT>, or shall refer to the
same entity, after overload resolution (12.2 [<A href="https://wg21.link/over.match">over.match</A>]) and
after matching of partial template specialization (13.10.4 [<A href="https://wg21.link/temp.over">temp.over</A>]), except that a name can refer to a const object with
internal or no linkage if the object has the same literal type in all
definitions of <TT>D</TT>, and the object is initialized with a
constant expression (7.7 [<A href="https://wg21.link/expr.const">expr.const</A>]), and the value (but
not the address) of the object is used, and the object has the same
value in all definitions of <TT>D</TT>

</BLOCKQUOTE>

<P>This could be read either way, since overload resolution isn't done
at this point.  Either we consider the result of the unqualified name
lookup and say that the expressions aren't equivalent or we need a
new rule for equivalence and merging of dependent calls.</P>

<P><B>Proposed resolution (December, 2011):</B></P>

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

<BLOCKQUOTE>

<P>Two expressions involving template parameters are considered
<I>equivalent</I> if two function definitions containing the
expressions would satisfy the one definition rule (6.3 [<A href="https://wg21.link/basic.def.odr">basic.def.odr</A>]), except that the tokens used to name the template
parameters may differ as long as a token used to name a template
parameter in one expression is replaced by another token that names
the same template parameter in the other expression. <INS>For
determining whether two dependent names (13.8.3 [<A href="https://wg21.link/temp.dep">temp.dep</A>])
are equivalent, only the name itself is considered, not the result of
name lookup in the context of the template. If multiple declarations
of the same function template differ in the result of this name
lookup, the result for the first declaration is used.</INS>
[<I>Example:</I>
</P>

<PRE>
  template &lt;int I, int J&gt; void f(A&lt;I+J&gt;); //<SPAN CLASS="cmnt"> #1</SPAN>
  template &lt;int K, int L&gt; void f(A&lt;K+L&gt;); //<SPAN CLASS="cmnt"> same as #1</SPAN>

<INS>  template &lt;class T&gt; decltype(g(T())) h();
  int g(int);
  template &lt;class T&gt; decltype(g(T())) h() //<SPAN CLASS="cmnt"> redeclaration of </SPAN>h()<SPAN CLASS="cmnt"> uses the earlier lookup</SPAN>
    { return g(T()); }                    //<SPAN CLASS="cmnt"> ...although the lookup here does find </SPAN>g(int)
  int i = h&lt;int&gt;();                       //<SPAN CLASS="cmnt"> template argument substitution fails; </SPAN>g(int)
                                          //<SPAN CLASS="cmnt"> was not in scope at the first declaration of </SPAN>h()</INS>
</PRE>

<P>&#8212;<I>end example</I>] Two expressions...</P>

</BLOCKQUOTE>

<LI><P>Change 13.8.3 [<A href="https://wg21.link/temp.dep#1">temp.dep</A>] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>...In an expression of the form:</P>

<UL>
<I>postfix-expression</I> <TT>(</TT> <I>expression-list<SUB>opt</SUB></I> <TT>)</TT>
</UL>

<P>where the <I>postfix-expression</I> is an
<DEL><I>id-expression</I></DEL> <INS><I>unqualified-id</I></INS>, the
<DEL><I>id-expression</I></DEL> <INS><I>unqualified-id</I></INS>
denotes a dependent name if</P>

<UL>
<LI><P>any of the expressions in the <I>expression-list</I> is a pack
expansion (13.7.4 [<A href="https://wg21.link/temp.variadic">temp.variadic</A>]),</P></LI>

<LI><P>any of the expressions in the <I>expression-list</I> is a
type-dependent expression (13.8.3.3 [<A href="https://wg21.link/temp.dep.expr">temp.dep.expr</A>]), or</P></LI>

<LI><P>if the <I>unqualified-id</I> <DEL>of the
<I>id-expression</I></DEL> is a
<I>template-id</I> in which any of the template arguments depends on a
template parameter.</P></LI>

</UL>

<P>if an operand...</P>

</BLOCKQUOTE>

<LI><P>Change 13.8.4.2 [<A href="https://wg21.link/temp.dep.candidate#1">temp.dep.candidate</A>] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>For a function call <DEL>that depends on a template parameter</DEL>
<INS>where the <I>postfix-expression</I> is a dependent name</INS>,
the candidate functions are found using the usual lookup rules
(6.5.3 [<A href="https://wg21.link/basic.lookup.unqual">basic.lookup.unqual</A>], 6.5.4 [<A href="https://wg21.link/basic.lookup.argdep">basic.lookup.argdep</A>]<DEL>,
6.5.5 [<A href="https://wg21.link/basic.lookup.qual">basic.lookup.qual</A>]</DEL>) except that:</P>

<UL>
<LI><P>For the part of the lookup using unqualified name lookup
(6.5.3 [<A href="https://wg21.link/basic.lookup.unqual">basic.lookup.unqual</A>]) <DEL>or qualified name lookup (6.5.5 [<A href="https://wg21.link/basic.lookup.qual">basic.lookup.qual</A>])</DEL>, only function declarations from the template
definition context are found.</P></LI>

<LI><P>For the part of the lookup using associated namespaces
(6.5.4 [<A href="https://wg21.link/basic.lookup.argdep">basic.lookup.argdep</A>]), only function declarations found in
either the template definition context or the template instantiation
context are found.</P></LI>

</UL>

<P>If <DEL>the function name is an <I>unqualified-id</I> and</DEL> the
call would be ill-formed or would find a better match had the lookup
within the associated namespaces considered all the function
declarations with external linkage introduced in those namespaces in
all translation units, not just considering those declarations found
in the template definition and template instantiation contexts, then
the program has undefined behavior.</P>

</BLOCKQUOTE>

</OL>

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