<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[C++0x Lambdas: &amp;quot;Recapturing&amp;quot;?]]></title><description><![CDATA[<p>Ich möchte gerne in einem Lambda die gecapturete Referenz gleich an eine weitere geschachtelte Lmabda abgeben:</p>
<pre><code class="language-cpp">const std::array&lt;InterfaceEvent, 3&gt; pattern = 
  {
    CREATE_EVENT(InterfaceEvent, CUSTOM, &quot;N1&quot;),
    CREATE_EVENT(InterfaceEvent, CUSTOM, &quot;N2&quot;),
    CREATE_EVENT(InterfaceEvent, CUSTOM, &quot;N3&quot;)
  };

  InterfaceEventQueue queue;
  BOOST_CHECK(!queue.hasEvent());
  boost::thread pusher([&amp;queue, pattern]()
  {
    //InterfaceEventQueue&amp; q = queue;
    std::for_each(pattern.begin(), pattern.end(), [&amp;queue](InterfaceEvent const&amp; evt) //(!)
    {
      queue.pushEvent(evt);
    });
  });

  /* ... */
</code></pre>
<p>Ich kriege im MSVC in der Zeile mit dem //(!) jetzt folgende Meldung:</p>
<pre><code>\test_interfaceeventqueue.cpp(49): error C3480: 'test_InterfaceEventQueue::`anonymous-namespace'::&lt;lambda0&gt;::queue': a lambda capture variable must be from an enclosing function scope
</code></pre>
<p>Aus dem Grund habe ich die (hier auskommentierte) Zeile mit der Referenz zur &quot;Umbenennung&quot; von queue eingebaut und gebe stattdessen q an die innere Lambda.</p>
<p>Meine Frage ist jetzt: Ist das Standardkonform, und macht gcc das auch? (Mein gcc-Versuchskaninchen ideone hat grade die Grätsche gemacht, hoffentlich war ichs nicht)<br />
Ich hätte eigentlich erwartet, dass die Namen weitergereicht werden können - wäre nicht der erste Bug im Name-Lookup mit Lambdas, über den ich im MSVC 2010 stolpere...</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/294204/c-0x-lambdas-quot-recapturing-quot</link><generator>RSS for Node</generator><lastBuildDate>Sat, 15 Aug 2026 22:38:31 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/294204.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 19 Oct 2011 20:11:58 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to C++0x Lambdas: &amp;quot;Recapturing&amp;quot;? on Wed, 19 Oct 2011 20:11:58 GMT]]></title><description><![CDATA[<p>Ich möchte gerne in einem Lambda die gecapturete Referenz gleich an eine weitere geschachtelte Lmabda abgeben:</p>
<pre><code class="language-cpp">const std::array&lt;InterfaceEvent, 3&gt; pattern = 
  {
    CREATE_EVENT(InterfaceEvent, CUSTOM, &quot;N1&quot;),
    CREATE_EVENT(InterfaceEvent, CUSTOM, &quot;N2&quot;),
    CREATE_EVENT(InterfaceEvent, CUSTOM, &quot;N3&quot;)
  };

  InterfaceEventQueue queue;
  BOOST_CHECK(!queue.hasEvent());
  boost::thread pusher([&amp;queue, pattern]()
  {
    //InterfaceEventQueue&amp; q = queue;
    std::for_each(pattern.begin(), pattern.end(), [&amp;queue](InterfaceEvent const&amp; evt) //(!)
    {
      queue.pushEvent(evt);
    });
  });

  /* ... */
</code></pre>
<p>Ich kriege im MSVC in der Zeile mit dem //(!) jetzt folgende Meldung:</p>
<pre><code>\test_interfaceeventqueue.cpp(49): error C3480: 'test_InterfaceEventQueue::`anonymous-namespace'::&lt;lambda0&gt;::queue': a lambda capture variable must be from an enclosing function scope
</code></pre>
<p>Aus dem Grund habe ich die (hier auskommentierte) Zeile mit der Referenz zur &quot;Umbenennung&quot; von queue eingebaut und gebe stattdessen q an die innere Lambda.</p>
<p>Meine Frage ist jetzt: Ist das Standardkonform, und macht gcc das auch? (Mein gcc-Versuchskaninchen ideone hat grade die Grätsche gemacht, hoffentlich war ichs nicht)<br />
Ich hätte eigentlich erwartet, dass die Namen weitergereicht werden können - wäre nicht der erste Bug im Name-Lookup mit Lambdas, über den ich im MSVC 2010 stolpere...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2133504</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2133504</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 19 Oct 2011 20:11:58 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x Lambdas: &amp;quot;Recapturing&amp;quot;? on Wed, 19 Oct 2011 21:34:52 GMT]]></title><description><![CDATA[<p>Scheint eine ganz witzige Sache zu sein. Aber vorweg was anderes: Ich bin müde, habe letzte Nacht kaum schlafen können und bin noch nicht wirklich sattelfest im neuen Standard. Also die folgenden Aussagen mit Vorsicht geniessen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>Also meiner Meinung nach sollte dies problemlos funktionieren. Ich stütze mich dabei vor allem auf §5.1.2 Lambda Expressions, Clause 16.</p>
<blockquote>
<p>If a lambda-expression m2 captures an entity and that entity is captured by an immediately enclosing lambda-expression m1, then m2’s capture is transformed as follows:<br />
— if m1 captures the entity by copy, m2 captures the corresponding non-static data member of m1’s closure type;<br />
— if m1 captures the entity by reference, m2 captures the same entity captured by m1.</p>
<p>[ Example: the nested lambda expressions and invocations below will output 123234.</p>
<pre><code class="language-cpp">int a = 1, b = 1, c = 1;
auto m1 = [a, &amp;b, &amp;c]() mutable {
  auto m2 = [a, b, &amp;c]() mutable {
    std::cout &lt;&lt; a &lt;&lt; b &lt;&lt; c;
    a = 4; b = 4; c = 4;
  };
  a = 3; b = 3; c = 3;
  m2();
};
a = 2; b = 2; c = 2;
m1();
std::cout &lt;&lt; a &lt;&lt; b &lt;&lt; c;
</code></pre>
<p>- end example]</p>
</blockquote>
<p>Einfache Beispielanwendung:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

int main()
{
  int x = 0;

  auto outer = [&amp;x]() {
    auto inner = [&amp;x]() {
      ++x;
      std::cout &lt;&lt; x &lt;&lt; '\n';
    };

    inner();
  };

  std::cout &lt;&lt; x &lt;&lt; '\n';

  outer();

  std::cout &lt;&lt; x &lt;&lt; '\n';

  return 0;
}
</code></pre>
<p>Kompiliert unter GCC 4.6.1 einwandfrei. Unter VS2010 gibt es den angegebenen Fehler.</p>
<p>Jetzt zum witzigen Teil:<br />
23.05.2010 -&gt; <a href="http://connect.microsoft.com/VisualStudio/feedback/details/560907/capturing-variables-in-nested-lambdas" rel="nofollow">http://connect.microsoft.com/VisualStudio/feedback/details/560907/capturing-variables-in-nested-lambdas</a></p>
<p>-&gt; Bug bestätigt, Workaround bekannt (nämlich deiner), won't fix in next release</p>
<p>07.06.2010 -&gt; <a href="http://connect.microsoft.com/VisualStudio/feedback/details/565418/visual-c-project-can-run-with-error-reported" rel="nofollow">http://connect.microsoft.com/VisualStudio/feedback/details/565418/visual-c-project-can-run-with-error-reported</a></p>
<p>-&gt; Bug nicht bestätigt, by Design, berufen sich auf:<br />
<a href="http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2009/n2927.pdf" rel="nofollow">http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2009/n2927.pdf</a> 5.1.1 Clause 9<br />
Was aber veraltet ist und im aktuellen Standard so nicht mehr drin steht.</p>
<p>Und nun noch zum letzten Workaround:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

int main()
{
  int x = 0;

  auto outer = [&amp;]() {
    auto inner = [&amp;]() {
      ++x;
      std::cout &lt;&lt; x &lt;&lt; '\n';
    };

    inner();
  };

  std::cout &lt;&lt; x &lt;&lt; '\n';

  outer();

  std::cout &lt;&lt; x &lt;&lt; '\n';

  return 0;
}
</code></pre>
<p>Funktioniert unter VS2010 und GCC 4.6.1.</p>
<p>Meiner Meinung nach definitiv ein Fehler von MSVC. Sollte man vielleicht als Bug melden. Ausser natürlich ich hätte nun etwas in meiner Müdigkeit übersehen, daher bitte ich dringend um eine Gegenprüfung <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2133536</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2133536</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Wed, 19 Oct 2011 21:34:52 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x Lambdas: &amp;quot;Recapturing&amp;quot;? on Wed, 19 Oct 2011 21:37:52 GMT]]></title><description><![CDATA[<p>Ist hier mit &quot;won't fix in next release&quot; auch ncoh der VC12 gemeint?</p>
<p>MfG SideWinder</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2133537</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2133537</guid><dc:creator><![CDATA[SideWinder]]></dc:creator><pubDate>Wed, 19 Oct 2011 21:37:52 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x Lambdas: &amp;quot;Recapturing&amp;quot;? on Thu, 20 Oct 2011 06:21:03 GMT]]></title><description><![CDATA[<p>SideWinder schrieb:</p>
<blockquote>
<p>Ist hier mit &quot;won't fix in next release&quot; auch ncoh der VC12 gemeint?</p>
<p>MfG SideWinder</p>
</blockquote>
<p>Ich nehme mal an, &quot;Next release&quot; ist VC11, wo sie kleinere Bugs nicht fixen wollen.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/9752">@Dravere</a>: <a href="http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2009/n2957.html" rel="nofollow">http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2009/n2957.html</a> &quot;beschwert&quot; sich bereits über n2927. ALlerdings stellt sich die Frage, wann der Draft entsprechend geändert wurde, dass Recapturing möglich wäre. Der MS-Bug ist bereits ende Juni 2010 geschlossen worden, danach kann noch vieles passiert sein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2133574</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2133574</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Thu, 20 Oct 2011 06:21:03 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x Lambdas: &amp;quot;Recapturing&amp;quot;? on Mon, 24 Oct 2011 12:50:31 GMT]]></title><description><![CDATA[<p>SideWinder, meinst du VC12 oder VS 2012? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2135100</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2135100</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Mon, 24 Oct 2011 12:50:31 GMT</pubDate></item></channel></rss>