<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    CWG Issue 1664</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="1664"></A><H4>1664.
  
Argument-dependent lookup of lambdas used in default arguments
</H4>
<B>Section: </B>7.5.6&#160; [<A href="https://wg21.link/expr.prim.lambda">expr.prim.lambda</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>2013-04-15<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3903.html#CA18">N3690 comment
  CA&#160;18<BR></A>

<P>[Moved to DR at the February, 2014 meeting.]</P>



<P>According to 7.5.6 [<A href="https://wg21.link/expr.prim.lambda#3">expr.prim.lambda</A>] paragraph 3,</P>

<BLOCKQUOTE>

The closure type is declared in the smallest block scope, class scope, or
namespace scope that contains the
corresponding <I>lambda-expression</I>. [<I>Note:</I> This determines the
set of namespaces and classes associated with the closure type
(6.5.4 [<A href="https://wg21.link/basic.lookup.argdep">basic.lookup.argdep</A>]). The parameter types of
a <I>lambda-declarator</I> do not affect these associated namespaces and
classes. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<P>However, 13.9.2 [<A href="https://wg21.link/temp.inst#13">temp.inst</A>] paragraph 13 says,</P>

<BLOCKQUOTE>

If a function template <TT>f</TT> is called in a way that requires a
default argument to be used, the dependent names are looked up, the
semantics constraints are checked, and the instantiation of any template
used in the default argument is done as if the default argument had been an
initializer used in a function template specialization with the same scope,
the same template parameters and the same access as that of the function
template <TT>f</TT> used at that point.

</BLOCKQUOTE>

<P>A possibility, then, is that the closure type for a lambda expression in
a default argument for a template function (or, presumably, a member
function of a class template) is to be considered as having been declared
in some block scope in the body of the fictional function template
specialization.</P>

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

<PRE>
  namespace J {
    inline namespace K {
      template &lt;typename T&gt; int zap(const T &amp;t) { foo(t); return 0; }
      template &lt;typename T&gt; void zip(int = zap([] { })) { }
    }
    template &lt;typename T&gt; void foo(const T &amp;) { }
  }
  void bar() { J::K::zip&lt;long&gt;(); }
</PRE>

<P>If <TT>zip</TT> were not a template, argument-dependent lookup
successfully resolves the lookup for <TT>foo</TT> in all implementations
tested; however, there is implementation variance in the handling of the
example as written.</P>

<P>(See also <A HREF="1690.html">issue 1690</A>.)</P>

<P><B>Proposed resolution (September, 2013):</B></P>

<P>Change 13.9.2 [<A href="https://wg21.link/temp.inst#13">temp.inst</A>] paragraph 13 as follows:</P>

<BLOCKQUOTE>

If a function template <TT>f</TT> is called in a way that requires a
default argument to be used, the dependent names are looked up, the
semantics constraints are checked, and the instantiation of any template
used in the default argument is done as if the default argument had been an
initializer used in a function template specialization with the same scope,
the same template parameters and the same access as that of the function
template <TT>f</TT> used at that point<INS>, except that the scope in which
a closure type is declared (7.5.6 [<A href="https://wg21.link/expr.prim.lambda">expr.prim.lambda</A>]) &#8212; and
therefore its associated namespaces &#8212; remain as determined from the
context of the definition for the default argument</INS>. This analysis is
called <I>default argument instantiation</I>. The instantiated default
argument is then used as the argument of <TT>f</TT>.

</BLOCKQUOTE>

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