<html><head><title>N3649 Wording for Auto Generic Lambda Proposal (Bristol 2013)</title><style type="text/css">@import url('https://themes.googleusercontent.com/fonts/css?kit=na2xy4REgy2vjVAZtpZNc_yDN7cgeRfA_woaXUgMUYU');ol{margin:0;padding:0}.c14{list-style-type:disc;margin:0;padding:0}.c28{max-width:451.3pt;background-color:#ffffff;padding:72pt 72pt 72pt 72pt}.c16{background-color:#ffa0a0;text-decoration:line-through}.c9{direction:ltr;margin-left:36pt}.c7{text-align:center;direction:ltr}.c0{font-size:10pt;font-family:"Consolas"}.c4{text-align:justify;margin-left:18pt}.c3{height:12pt;direction:ltr}.c24{color:#1155cc;text-decoration:underline}.c31{color:inherit;text-decoration:inherit}.c11{font-size:18pt;font-weight:bold}.c6{direction:ltr;margin-left:18pt}.c26{text-align:right}.c10{padding-left:0pt}.c1{background-color:#a0ffa0}.c2{font-style:italic}.c17{margin-left:13pt}.c30{text-indent:36pt}.c13{font-weight:bold}.c19{font-size:18pt}.c25{background-color:#d9d2e9}.c12{direction:ltr}.c27{font-size:17pt}.c15{line-height:1.15}.c21{text-align:justify}.c18{margin-left:18pt}.c8{font-size:14pt}.c22{margin-left:27pt}.c5{background-color:#93c47d}.c29{text-decoration:line-through}.c23{background-color:#ffa0a0}.c20{height:12pt}.title{padding-top:12pt;line-height:1.0;text-align:center;color:#000000;font-size:16pt;font-family:"Arial";font-weight:bold;padding-bottom:3pt}.subtitle{padding-top:0pt;line-height:1.0;text-align:center;color:#000000;font-size:12pt;font-family:"Arial";padding-bottom:3pt}li{color:#000000;font-size:12pt;font-family:"Times New Roman"}p{color:#000000;font-size:12pt;margin:0;font-family:"Times New Roman"}h1{padding-top:12pt;line-height:1.0;text-align:left;color:#000000;font-size:16pt;font-family:"Arial";font-weight:bold;padding-bottom:3pt}h2{padding-top:12pt;line-height:1.0;text-align:left;color:#000000;font-style:italic;font-size:14pt;font-family:"Arial";font-weight:bold;padding-bottom:3pt}h3{padding-top:12pt;line-height:1.0;text-align:left;color:#000000;font-size:13pt;font-family:"Arial";font-weight:bold;padding-bottom:3pt}h4{padding-top:12pt;line-height:1.0;text-align:left;color:#000000;font-size:14pt;font-family:"Times New Roman";font-weight:bold;padding-bottom:3pt}h5{padding-top:12pt;line-height:1.0;text-align:left;color:#000000;font-style:italic;font-size:13pt;font-family:"Times New Roman";font-weight:bold;padding-bottom:3pt}h6{padding-top:12pt;line-height:1.0;text-align:left;color:#000000;font-size:12pt;font-family:"Times New Roman";font-weight:bold;padding-bottom:3pt}</style></head><body class="c28"><div><p class="c12"><span>N3649</span></p></div><h4 class="c7"><a name="h.e5ltpqwk1d66"></a><span class="c19">Generic (Polymorphic) Lambda Expressions (Revision 3) </span></h4><p class="c7"><span class="c8">Document no: N3649</span></p><p class="c7 c20"><span class="c27"></span></p><p class="c7"><span class="c8">Faisal Vali &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Herb Sutter &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dave Abrahams</span></p><p class="c7"><span class="c27">2013-04-19</span></p><p class="c12"><span class="c11">1 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Introduction</span></p><p class="c3 c15"><span class="c11"></span></p><p class="c12 c21"><span>This document revises wording for generic lambda expressions as described in</span><span>&nbsp;</span><span class="c24"><a class="c31" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3559.pdf">N3559</a></span><span>: Proposal for Generic (Polymorphic) Lambda Expressions (Revision 2) and as </span><span class="c24"><a class="c31" href="http://wiki.edg.com/twiki/bin/view/Wg21bristol/EvolutionWorkingGroup">approved by EWG</a></span><span>&nbsp;and </span><span>which should be referenced for further detail. &nbsp;Today&rsquo;s C++11 lambda expression concisely creates an instance of a class having a non-template function call operator. &nbsp;We propose a pure extension of C++11 lambda syntax that creates an instance of a class having a function call operator template. &nbsp;</span></p><p class="c12"><span>&nbsp;</span></p><p class="c12"><span>Here follow some examples of the proposed syntax extension in use:</span></p><p class="c12"><span>&nbsp; &nbsp;</span></p><p class="c12"><span class="c0">&nbsp;// &#39;Identity&#39; is a lambda that accepts an argument of any type and</span></p><p class="c12"><span class="c0">&nbsp;// returns the value of its parameter. &nbsp;</span></p><p class="c17 c12 c15"><span class="c0">auto Identity = [](auto a) { return a; };</span></p><p class="c17 c12 c15"><span class="c0">int three = Identity(3);</span></p><p class="c17 c12 c15"><span class="c0">char const* hello = Identity(&quot;hello&quot;);</span></p><p class="c3 c15"><span class="c0"></span></p><p class="c12 c15"><span class="c0">&nbsp;// Conversion to function pointer for capture-less lambdas</span></p><p class="c17 c12 c15"><span class="c0">int (*fpi)(int) = Identity;</span></p><p class="c12 c15 c17"><span class="c0">char (*fpc)(char) = Identity;</span><span>&nbsp; &nbsp; &nbsp; &nbsp;</span></p><p class="c3 c15"><span></span></p><p class="c3"><span></span></p><p class="c12"><span class="c11">2 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Proposal</span></p><p class="c3 c15"><span class="c11"></span></p><p class="c12"><span>We are proposing the following pure extensions to C++11:</span></p><p class="c3 c15"><span></span></p><ol class="c14" start="1"><li class="c9 c10"><span>Allow </span><span class="c0 c13">auto</span><span>&nbsp;</span><span class="c2">type-specifier</span><span>&nbsp;to indicate a generic lambda parameter</span></li><li class="c9 c10"><span>Allow conversion from a capture-less generic lambda to an appropriate pointer-to-function</span></li></ol><p class="c3 c15"><span></span></p><p class="c12"><span>Each of these is discussed in further detail in N3559.</span></p><p class="c12"><span class="c11">&nbsp;</span></p><p class="c12"><span class="c11">3 &nbsp; &nbsp; &nbsp;Changes from N3559 &nbsp;</span></p><p class="c3"><span></span></p><ol class="c14" start="1"><li class="c9 c10"><span>Added wording to support variadic auto parameters </span></li></ol><p class="c3"><span></span></p><ol class="c14" start="2"><li class="c9 c10"><span>Return type deduction of the pointer to function conversion operator wording has been reworded in terms of decltype</span></li></ol><p class="c3"><span></span></p><ol class="c14" start="3"><li class="c9 c10"><span>Specified the definition of implicit capture using a list and incorporated the change from</span><span>&nbsp;N3648. &nbsp;Applied wording for capturing variables named in expressions dependent on a generic lambda parameter to a non-generic lambda (so that if it is present within a nested chain it too can capture appropriately) </span></li></ol><p class="c3"><span></span></p><ol class="c14" start="4"><li class="c9 c10"><span>Acknowledge return type deduction of placeholder types </span></li></ol><p class="c3"><span></span></p><ol class="c14" start="5"><li class="c9 c10"><span>Remove redundant (already covered in 5.1.2 paragraph 11) and potentially misplaced wording in 5.1.2 paragraph 12 about certain dependent expressions capturing variables AND instead add a phrase reinforcing that if instantiation of the function call operator template odr-uses a variable, it needs to be capture</span></li></ol><p class="c3"><span></span></p><ol class="c14" start="6"><li class="c9 c10"><span>Added additional examples and notes</span></li></ol><p class="c3"><span class="c8"></span></p><ol class="c14" start="7"><li class="c9 c10"><span>unhyphenated pointer-to-function; hyphenated and italicized trailing-return-type; potentially-evaluated has been un-italicized, requested commas have been added</span></li></ol><p class="c3"><span></span></p><p class="c3"><span></span></p><p class="c12"><span>NOTE: Wording that has been added as compared to N3559 is a darker shade of green</span></p><p class="c3 c30"><span></span></p><p class="c3"><span class="c11"></span></p><p class="c12"><span class="c11">Changes to the Working Draft</span></p><p class="c3"><span></span></p><p class="c4 c12"><span>Change in 7.1.6.4 &nbsp;dcl.spec.auto paragraph 1:</span></p><p class="c4 c3"><span></span></p><p class="c4 c12"><span>The </span><span class="c0 c13">auto</span><span>&nbsp;</span><span class="c2">type-specifier</span><span>&nbsp;signifies that the type of a variable being declared shall be deduced from its initializer</span><span class="c1">,</span><span>&nbsp;or that a function declarator shall include a </span><span class="c2">trailing-return-type</span><span class="c1">, or that a lambda is a generic lambda</span><span>.</span></p><p class="c4 c3"><span class="c23"></span></p><p class="c4 c12"><span>Change in 7.1.6.4 &nbsp;dcl.spec.auto, add after paragraph 2:</span></p><p class="c4 c3"><span class="c23"></span></p><p class="c4 c12"><span class="c1">Otherwise, if the </span><span class="c0 c1 c13">auto</span><span class="c1">&nbsp;</span><span class="c1 c2">type-specifier</span><span class="c1">&nbsp;appears as one of the </span><span class="c1 c2">decl-specifier</span><span class="c1">s</span><span class="c1">&nbsp;in the </span><span class="c1 c2">decl-specifier-seq </span><span class="c1">of a </span><span class="c1 c2">parameter-declaration</span><span class="c1">&nbsp;of a </span><span class="c1 c2">lambda-expression</span><span class="c1">, the lambda is a </span><span class="c1 c2">generic lambda</span><span class="c1">&nbsp;(5.1.2 expr.prim.lambda).</span><span class="c5">&nbsp;[ </span><span class="c2 c5">Example: </span><span class="c5">&nbsp; &nbsp;</span></p><p class="c6"><span class="c0 c5">&nbsp; auto glambda = [](int i, auto a) { return i; }; // OK: </span><span class="c0 c2 c5">a generic lambda</span></p><p class="c6"><span class="c13 c5">&mdash;</span><span class="c5">&nbsp;</span><span class="c2 c5">end example]</span></p><p class="c4 c3"><span class="c23"></span></p><p class="c4 c12"><span>Change in 5.1.2 &nbsp;expr.prim.lambda paragraph 5:</span></p><p class="c3 c4"><span></span></p><p class="c4 c12"><span>The closure type for a </span><span class="c1">non-generic </span><span class="c2">lambda-expression</span><span>&nbsp;has a public inline function call operator (13.5.4) </span><span>whose parameters and return type are </span><span>described by</span><span>&nbsp;the</span><span class="c2">&nbsp;lambda-expression&rsquo;s parameter-declaration-clause</span><span>&nbsp;and </span><span class="c2">trailing</span><span class="c2">-</span><span class="c2">return-type</span><span>&nbsp;respectively.</span><span class="c1">&nbsp;</span><span class="c1">&nbsp; For a generic lambda, the closure type has a public inline function call operator member template (14.5.2 temp.mem) whose </span><span class="c1 c2">template-parameter-list</span><span class="c1">&nbsp;consists of one invented type </span><span class="c1 c2">template-parameter</span><span class="c1">&nbsp;for each occurrence of </span><span class="c0 c1 c13">auto</span><span class="c1">&nbsp;in the lambda&#39;s </span><span class="c1 c2">parameter-declaration-clause</span><span class="c1">, in order of appearance. &nbsp;</span><span class="c5">The invented type </span><span class="c2 c5">template-parameter</span><span class="c5">&nbsp;is a parameter pack</span><span class="c2 c5">&nbsp;</span><span class="c5">if the corresponding </span><span class="c2 c5">parameter-declaration </span><span class="c5">declares a function parameter pack (8.3.5 dcl.fct). </span><span class="c1">&nbsp;The return type and function parameters of the function call operator template are derived from the </span><span class="c1 c2">lambda-expression&#39;</span><span class="c1">s</span><span class="c1 c2">&nbsp;trailing-return-type </span><span class="c1">and </span><span class="c1 c2">parameter-declaration-clause </span><span class="c1">by replacing each occurrence of </span><span class="c0 c1 c13">auto</span><span class="c1 c13">&nbsp;</span><span class="c1">in the </span><span class="c1 c2">decl-specifier</span><span class="c1">s</span><span class="c1 c2">&nbsp;</span><span class="c5">of the </span><span class="c2 c5">parameter-declaration-clause</span><span class="c1">&nbsp;with the name of the corresponding invented </span><span class="c1 c2">template-parameter</span><span class="c1">.</span><span class="c5">&nbsp;[ </span><span class="c2 c5">Example: </span></p><p class="c6"><span class="c5">&nbsp; &nbsp; </span><span class="c0 c5">auto glambda &nbsp;= [](auto a, auto&amp;&amp; b) { return &nbsp;a &lt; b; }; </span></p><p class="c6"><span class="c0 c5">&nbsp; bool b = glambda(3, 3.14); &nbsp; &nbsp; &nbsp; // OK</span></p><p class="c6"><span class="c0 c5">&nbsp; auto vglambda = [](auto printer) {</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; &nbsp;return [=](auto&amp;&amp; ... ts) { &nbsp; // OK: </span><span class="c0 c2 c5">ts is a &nbsp;function parameter pack</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;printer(std::forward&lt;decltype(ts)&gt;(ts)...);</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return [=]() {</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;printer(ts ...);</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;};</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; &nbsp;};</span></p><p class="c6"><span class="c0 c5">&nbsp; }; </span></p><p class="c6"><span class="c0 c5">&nbsp; auto p = vglambda( [](auto v1, auto v2, auto v3) &nbsp; &nbsp; </span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ std::cout &lt;&lt; v1 &lt;&lt; v2 &lt;&lt; v3; } );</span></p><p class="c6"><span class="c0 c5">&nbsp; auto q = p(1, &#39;a&#39;, 3.14); &nbsp;// OK: </span><span class="c0 c2 c5">outputs 1a3.14</span></p><p class="c6"><span class="c0 c5">&nbsp; q(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // OK: </span><span class="c0 c2 c5">outputs 1a3.14</span></p><p class="c4 c12"><span class="c13 c5">&mdash;</span><span class="c5">&nbsp;</span><span class="c2 c5">end example]</span><span class="c5">&nbsp;</span><span>This function call operator </span><span class="c1">or operator template </span><span>is declared </span><span class="c13">const</span><span>&nbsp;(9.3.1) if and only if the </span><span class="c2">lambda expression</span><span>&rsquo;s </span><span class="c2">parameter-declaration-clause</span><span>&nbsp;is not followed by </span><span class="c0 c13">mutable</span><span>. It is neither </span><span class="c0 c13">virtual</span><span>&nbsp;nor declared </span><span class="c0 c13">volatile</span><span>. Default arguments (8.3.6) shall not be specified in the </span><span class="c2">parameter-declaration-clause</span><span>&nbsp;of a </span><span class="c2">lambda declarator</span><span>. &nbsp;Any </span><span class="c2">exception-specification</span><span>&nbsp;specified on a </span><span class="c2">lambda-expression</span><span>&nbsp;applies to the corresponding function call operator </span><span class="c1">or operator template</span><span>. An </span><span class="c2">attribute-specifier-seq</span><span>&nbsp;in a </span><span class="c2">lambda-declarator</span><span>&nbsp;appertains to the type of the corresponding function call operator </span><span class="c1">or operator template</span><span>. [ Note: Names referenced in the </span><span class="c2">lambda-declarator</span><span>&nbsp;are looked up in the context in which the lambda-expression appears. &mdash;end note ]</span></p><p class="c4 c3"><span></span></p><p class="c4 c3"><span></span></p><p class="c4 c12"><span>Change in 5.1.2 &nbsp;expr.prim.lambda paragraph 6:</span></p><p class="c4 c3"><span></span></p><p class="c4 c12"><span>The closure type for a </span><span class="c1">non-generic </span><span class="c2">lambda-expression</span><span>&nbsp;with no </span><span class="c2">lambda-capture</span><span>&nbsp;has a </span><span class="c0 c13">public</span><span>&nbsp;non-virtual non-explicit </span><span class="c0 c13">const</span><span>&nbsp;conversion function to pointer to function</span><span class="c29">&nbsp;</span><span>having</span><span>&nbsp;</span><span>the same parameter and return types as the closure type&rsquo;s function call operator. &nbsp;The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type&rsquo;s function call operator. &nbsp;</span><span class="c1">For a generic lambda with no </span><span class="c1 c2">lambda-capture, </span><span class="c1">the closure type has a </span><span class="c0 c1 c13">public</span><span class="c1">&nbsp;non-virtual non-explicit </span><span class="c0 c1 c13">const</span><span class="c1">&nbsp;conversion function template to pointer to function. </span><span class="c5">&nbsp;The conversion function template has the same</span><span class="c5">&nbsp;invented </span><span class="c2 c5">template-parameter-list</span><span class="c5">, and the pointer to function has the same parameter types, as the function call operator template. &nbsp;The return type of the pointer to function shall behave as if it were a </span><span class="c2 c5">decltype-specifier</span><span class="c5">&nbsp;denoting the return type of the corresponding function call operator template specialization. &nbsp;[ </span><span class="c2 c5">Note:</span><span class="c5">&nbsp;If the generic lambda has no </span><span class="c2 c5">trailing-return-type</span><span class="c5">&nbsp;or the </span><span class="c2 c5">trailing-return-type</span><span class="c5">&nbsp;contains a placeholder type, return type deduction of the corresponding function call operator template specialization has to be done. &nbsp;The corresponding specialization is that instantiation of the function call operator template with the same template arguments as those deduced for the conversion function template. &nbsp;Consider the following:</span></p><p class="c4 c12"><span class="c5">&nbsp;</span></p><p class="c6"><span class="c0 c5">&nbsp; auto glambda = [](auto a) { return a; };</span></p><p class="c6"><span class="c0 c5">&nbsp; int (*fp)(int) = glambda;</span></p><p class="c4 c12"><span class="c5">&nbsp;</span></p><p class="c4 c12"><span class="c5">The behavior of the conversion function of the </span><span class="c0 c5">glambda</span><span class="c5">&nbsp;above is like that of the following conversion function:</span></p><p class="c4 c3"><span class="c5"></span></p><p class="c6"><span class="c5">&nbsp; </span><span class="c0 c5">struct Closure {</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; template&lt;class T&gt; auto operator()(T t) const { ... }</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; template&lt;class T&gt; static auto lambda_call_operator_invoker(T a) {</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; &nbsp; // forwards execution to operator()(a) and therefore has </span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; &nbsp; // the same return type deduced &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; &nbsp; ...</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; }</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; template&lt;class T&gt; using fptr_t =</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; &nbsp; &nbsp;decltype(lambda_call_operator_invoker(declval&lt;T&gt;())) (*)(T);</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; </span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; template&lt;class T&gt; operator fptr_t&lt;T&gt;() const </span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; &nbsp; { return &amp;lambda_call_operator_invoker; }</span></p><p class="c6"><span class="c0 c5">&nbsp; }; </span><span class="c5">&mdash; </span><span class="c2 c5">end note</span><span class="c5">]</span></p><p class="c4 c3"><span class="c5"></span></p><p class="c4 c12"><span class="c5">[ </span><span class="c2 c5">Example:</span></p><p class="c6"><span class="c5">&nbsp;</span></p><p class="c6"><span class="c0 c5">&nbsp; void f1(int (*)(int)) &nbsp; { }</span></p><p class="c6"><span class="c0 c5">&nbsp; void f2(char (*)(int)) &nbsp;{ }</span></p><p class="c6"><span class="c0 c5">&nbsp;</span></p><p class="c6"><span class="c0 c5">&nbsp; void g(int (*)(int)) &nbsp; &nbsp;{ } &nbsp;// #1</span></p><p class="c6"><span class="c0 c5">&nbsp; void g(char (*)(char)) &nbsp;{ } &nbsp;// #2</span></p><p class="c6"><span class="c0 c5">&nbsp;</span></p><p class="c6"><span class="c0 c5">&nbsp; void h(int (*)(int)) &nbsp; &nbsp;{ } &nbsp; // #3</span></p><p class="c6"><span class="c0 c5">&nbsp; void h(char (*)(int)) &nbsp; { } &nbsp; // #4</span></p><p class="c6"><span class="c0 c5">&nbsp;</span></p><p class="c6"><span class="c0 c5">&nbsp;</span></p><p class="c6"><span class="c0 c5">&nbsp; auto glambda = [](auto a) { return a; };</span></p><p class="c6"><span class="c0 c5">&nbsp; f1(glambda); &nbsp;// OK</span></p><p class="c6"><span class="c0 c5">&nbsp; f2(glambda); &nbsp;// error: ID is not convertible</span></p><p class="c6"><span class="c0 c5">&nbsp; g(glambda); &nbsp; // error: ambiguous</span></p><p class="c6"><span class="c0 c5">&nbsp; h(glambda); &nbsp; // OK: calls #3 since it is convertible from ID</span></p><p class="c6"><span class="c5">&nbsp; &nbsp;</span><span class="c0 c5">int&amp; (*fpi)(int*) = [](auto* a) -&gt; auto&amp; { return *a; }; // OK</span></p><p class="c6"><span class="c0 c5">&nbsp;</span></p><p class="c4 c12"><span class="c5">&nbsp;&mdash; </span><span class="c2 c5">end example</span><span class="c5">]</span><span class="c1">&nbsp;The value returned by any given specialization of this conversion function template shall be the address of a function that, when invoked, has the same effect as invoking the generic lambda&#39;s corresponding function call operator template specialization</span><span class="c1">. [ </span><span class="c1 c2">Note</span><span class="c1">: This will result in the implicit instantiation of the generic lambda&#39;s body. &nbsp;</span><span class="c1">The instantiated generic lambda&#39;s return type and parameter types shall match</span><span class="c1">&nbsp;the return type and parameter types of the pointer to function </span><span class="c1 c13">&mdash;</span><span class="c1">&nbsp; </span><span class="c1 c2">end note</span><span class="c1">&nbsp;] </span><span class="c5">[ </span><span class="c2 c5">Example: </span></p><p class="c6"><span class="c0 c5">&nbsp; auto GL = [](auto a) { std::cout &lt;&lt; a; return a; };</span></p><p class="c6"><span class="c0 c5">&nbsp; int (*GL_int)(int) = GL; &nbsp;// OK: </span><span class="c0 c2 c5">through conversion function template </span></p><p class="c6"><span class="c0 c5">&nbsp; GL_int(3); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// OK: </span><span class="c0 c2 c5">same as GL(3)</span><span class="c0 c5">&nbsp; &nbsp; </span></p><p class="c4 c12"><span class="c13 c5">&mdash;</span><span class="c5">&nbsp;</span><span class="c2 c5">end example]</span><span class="c5">&nbsp; &nbsp;</span></p><p class="c4 c3"><span></span></p><p class="c12 c21"><span>Change in 5.1.2 expr.prim.lambda paragraph 11:</span></p><p class="c3 c21"><span></span></p><p class="c4 c12"><span class="c16">If a </span><span class="c16 c2">lambda-expression</span><span class="c16">&nbsp;has an associated </span><span class="c16 c2">capture-default</span><span class="c16">&nbsp;and its </span><span class="c16 c2">compound-statement</span><span class="c16">&nbsp;odr-uses (3.2) </span><span class="c16 c0 c13">this</span><span class="c16">&nbsp;or a variable with automatic storage duration and the odr-used entity is not explicitly captured, then the odr-used entity is said to be implicitly captured</span><span>. </span></p><p class="c4 c12"><span class="c5">A </span><span class="c2 c5">lambda-expression</span><span class="c5">&nbsp;with an associated </span><span class="c2 c5">capture-default</span><span class="c5">&nbsp;that does not explicitly capture </span><span class="c0 c13 c5">this</span><span class="c5">&nbsp;or a variable with automatic storage duration </span><span class="c25">INSERT from N3648: (this excludes any </span><span class="c2 c25">id-expression</span><span class="c25">&nbsp;that has been found to refer to an </span><span class="c2 c25">init-capture</span><span class="c25">&#39;s associated non-static data member)</span><span class="c5">, is said to </span><span class="c2 c5">implicitly capture</span><span class="c5">&nbsp; the entity (i.e </span><span class="c0 c13 c5">this</span><span class="c5">&nbsp;or a variable) if the </span><span class="c2 c5">compound-statement</span><span class="c5">:</span></p><p class="c12 c21 c22"><span class="c5">&mdash; odr-uses (3.2) the entity, or</span></p><p class="c12 c21 c22"><span class="c5">&mdash; names the entity in a potentially-evaluated expression (3.2 basic.def.odr) where the enclosing full-expression depends on a generic lambda parameter declared within the reaching scope of the </span><span class="c2 c5">lambda-expression</span><span class="c5">.</span></p><p class="c4 c12"><span class="c5">[ </span><span class="c2 c5">Example: </span></p><p class="c6"><span class="c0 c13 c5">&nbsp; </span></p><p class="c6"><span class="c0 c5">&nbsp; void f(int, const int (&amp;)[2] = {}) &nbsp; &nbsp;{ } &nbsp; // #1</span></p><p class="c6"><span class="c0 c5">&nbsp; void f(const int&amp;, const int (&amp;)[1]) &nbsp;{ } &nbsp; // #2</span></p><p class="c3 c18"><span class="c0 c5"></span></p><p class="c6"><span class="c0 c5">&nbsp; void test() {</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; const int x = 17;</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; auto g = [](auto a) {</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; &nbsp; f(x); &nbsp;// OK: </span><span class="c0 c2 c5">calls #1, does not capture x</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; };</span></p><p class="c6"><span class="c0 c5">&nbsp; </span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; auto g2 = [=](auto a) {</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; &nbsp; int selector[sizeof(a) == 1 ? 1 : 2]{};</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; &nbsp; f(x, selector); &nbsp;// OK: </span><span class="c0 c2 c5">is a dependent expression, so captures x</span></p><p class="c6"><span class="c0 c5">&nbsp; &nbsp; }; &nbsp; &nbsp;</span></p><p class="c6"><span class="c0 c5">&nbsp; } &nbsp;</span></p><p class="c4 c12"><span class="c13 c5">&mdash;</span><span class="c5">&nbsp;</span><span class="c2 c5">end example]</span><span class="c1 c2">&nbsp;</span><span class="c1">A</span><span class="c1">ll </span><span>such </span><span class="c1">&nbsp;implicitly captured </span><span>&nbsp;entities shall be declared within the reaching scope of the lambda expression. [ Note: The implicit capture of an entity by a nested </span><span class="c2">lambda-expression</span><span>&nbsp;can cause its implicit capture by the containing</span><span class="c2">&nbsp;lambda-expression</span><span>&nbsp;(see below). Implicit odr-uses of </span><span class="c0 c13">this</span><span>&nbsp;can result in implicit capture. &mdash; end note ]</span></p><p class="c4 c3"><span></span></p><p class="c4 c12"><span>Change in 5.1.2 expr.prim.lambda paragraph 12:</span></p><p class="c4 c3"><span></span></p><p class="c4 c12"><span>An entity is captured if it is captured explicitly or implicitly. An entity captured by a </span><span class="c2">lambda-expression</span><span>&nbsp;is odr-used (3.2) in the scope containing the </span><span class="c2">lambda-expression</span><span>. If </span><span class="c0 c13">this</span><span>&nbsp;is captured by a local lambda expression, its nearest enclosing function shall be a non-static member function. If a </span><span class="c2">lambda-expression</span><span>&nbsp;</span><span class="c5">or an instantiation of the function call operator template of a generic lambda</span><span>&nbsp;</span><span>odr-uses (3.2)</span><span class="c13">&nbsp;</span><span class="c0 c13">this</span><span>&nbsp;or a variable with automatic storage duration from its reaching scope, that entity shall be captured by the </span><span class="c2">lambda-expression</span><span>. If a </span><span class="c2">lambda-expression </span><span>captures an entity and that entity is not defined or captured in the immediately enclosing lambda expression or function, the program is ill-formed.</span></p><p class="c4 c3"><span></span></p><p class="c4 c3"><span></span></p><p class="c4 c12"><span>Change in 8.3.5 dcl.fct paragraph 14:</span></p><p class="c4 c3"><span></span></p><p class="c4 c12"><span>There is a syntactic ambiguity when an ellipsis occurs at the end of a </span><span class="c2">parameter-declaration-clause</span><span>&nbsp;without a preceding comma. In this case, the ellipsis is parsed as part of the </span><span class="c2">abstract-declarator</span><span>&nbsp;if the type of the parameter</span><span class="c13">&nbsp;</span><span class="c5">either</span><span class="c13">&nbsp;</span><span>names a template parameter pack that has not been expanded </span><span class="c5">or contains </span><span class="c0 c13 c5">auto</span><span>; otherwise, it is parsed as part of the </span><span class="c2">parameter-declaration-clause.</span></p><p class="c4 c3"><span></span></p><p class="c4 c12"><span>Change in 14.5.2 temp.mem paragraph 2:</span></p><p class="c4 c3"><span></span></p><p class="c4 c12"><span>A local class </span><span class="c1">of non-closure type </span><span>shall not have member templates.</span></p><p class="c3 c21"><span class="c8"></span></p><p class="c3"><span class="c8"></span></p><hr style="page-break-before:always;display:none;"><p class="c3"><span class="c8"></span></p><p class="c12"><span class="c11">6 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Acknowledgments</span></p><p class="c3"><span></span></p><p class="c12"><span>The authors would like to thank:</span></p><p class="c3"><span></span></p><p class="c9"><span>Jens Maurer for his indispensable assistance in writing the initial wording that accompanied the proposal N3559 and continued guidance.</span></p><p class="c9 c20"><span></span></p><p class="c9"><span>Doug Gregor for his continued guidance in delineating the semantics of capturing within generic lambdas, and for suggesting wording to support variadic packs.</span></p><p class="c3"><span></span></p><p class="c9"><span>Richard Smith for rescuing the conversion operator from being prohibited in generic lambdas with no </span><span class="c2">trailing-return-type</span><span>&nbsp;(</span><span>by suggesting wording using decltype semantics).</span></p><p class="c9 c20"><span></span></p><p class="c9"><span>Christof Meerwald and Richard Corden for identifying, in the initial wording, an ambiguity with the conversion to pointer to function.</span></p><p class="c9 c20"><span></span></p><p class="c9"><span>John Spicer and Daveed Vandevoorde for personally (off-hours) reviewing sections of the wording and providing precious feedback.</span></p><p class="c9 c20"><span></span></p><p class="c9"><span>Jason Merrill for his guidance with initial drafts of this wording.</span></p><p class="c3"><span></span></p><p class="c9"><span>All the members of the Core </span><span>subgroup who carefully provided valuable feedback during continued review of this wording. &nbsp;</span></p><p class="c3"><span></span></p><div><p class="c3 c26"><span></span></p></div></body></html>