<?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[Funktionsweise von boost::foreach und typeof]]></title><description><![CDATA[<pre><code class="language-cpp">//nur zum Textverständnis:
#define foreach BOOST_FOREACH
#define typeof BOOST_TYPEOF
</code></pre>
<p>Kann jemand anschaulich erklären, wie diese beiden Konstukte intern funktionieren? 'boost::typeof' kann ich mir nur damit erklären, dass das eine Art Makro auf irgendwelche Compiler-spezifischen '__type__of___'s oder dergleichen ist. Aber 'foreach'? Das sieht bei der Benutzung so aus:</p>
<pre><code class="language-cpp">#include &lt;boost/foreach.hpp&gt;
#include &lt;iostream&gt;
using namespace boost;
using namespace std;
int main()
{
	int arr[] = {1, 2, 3};
	BOOST_FOREACH(int i, arr)
	{
		cout &lt;&lt; i &lt;&lt; endl;
	}
	cin.get();
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/253467/funktionsweise-von-boost-foreach-und-typeof</link><generator>RSS for Node</generator><lastBuildDate>Sun, 13 Sep 2026 16:49:01 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/253467.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 02 Nov 2009 19:21:54 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Funktionsweise von boost::foreach und typeof on Mon, 02 Nov 2009 19:21:54 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">//nur zum Textverständnis:
#define foreach BOOST_FOREACH
#define typeof BOOST_TYPEOF
</code></pre>
<p>Kann jemand anschaulich erklären, wie diese beiden Konstukte intern funktionieren? 'boost::typeof' kann ich mir nur damit erklären, dass das eine Art Makro auf irgendwelche Compiler-spezifischen '__type__of___'s oder dergleichen ist. Aber 'foreach'? Das sieht bei der Benutzung so aus:</p>
<pre><code class="language-cpp">#include &lt;boost/foreach.hpp&gt;
#include &lt;iostream&gt;
using namespace boost;
using namespace std;
int main()
{
	int arr[] = {1, 2, 3};
	BOOST_FOREACH(int i, arr)
	{
		cout &lt;&lt; i &lt;&lt; endl;
	}
	cin.get();
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1802317</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1802317</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Mon, 02 Nov 2009 19:21:54 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionsweise von boost::foreach und typeof on Mon, 02 Nov 2009 19:37:50 GMT]]></title><description><![CDATA[<p>Das man mit einem Makro einen Schleifenkopf generieren kann, sollte klar sein. Dazu kommt dann ähnlich wie bei typeof eine clevere Erkennung des Typs des zweiten Arguments (mittels Makros und einer Menge Templatemetaprogrammierungsmagie). Damit wird dann die zum Typen passende Schleife generiert.</p>
<p>Für eine sehr vereinfachte Version dieser Typerkennung kannst du dir mal eine Einführung in Templatemetaprogrammierung angucken. Damit kannst du dir die zugrundeliegenden Konzepte klarmachen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1802328</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1802328</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Mon, 02 Nov 2009 19:37:50 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionsweise von boost::foreach und typeof on Mon, 02 Nov 2009 19:45:46 GMT]]></title><description><![CDATA[<p>Ich glaube, das muss man nicht wissen. Wie foreach genau funktioniert weiß ich nicht. Typeof braucht zumindest Hilfe vom Compilers (Compiler-Erweiterung) oder des Benutzers (Typen manuell registrieren), soweit ich weiß. Der GCC bietet zB eine Erweiterung an (<a href="http://gcc.gnu.org/onlinedocs/gcc/Typeof.html" rel="nofollow"> <code>__typeof__</code> </a>), die dann von Boost.Typeof einfach benutzt wird.</p>
<p>Spätestens mit C++0x wird sich das erledigt haben. Dann haben wir <a href="http://en.wikipedia.org/wiki/Decltype" rel="nofollow">decltype</a> und den <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2930.html" rel="nofollow">for-range loop</a>.</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1802330</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1802330</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Mon, 02 Nov 2009 19:45:46 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionsweise von boost::foreach und typeof on Mon, 02 Nov 2009 20:27:02 GMT]]></title><description><![CDATA[<p>Nach über 45 Minuten mit Experimenten kenne ich das Problem bei der Sache: Das ändern der Elementvariablen, im Beispiel 'int i'. Man hat ja nicht einfach den Namen, sondern es steht immer der Typ davor. Und es scheint keine Möglichkeit zu geben, eine Referenz darauf zu erhalten:</p>
<pre><code class="language-cpp">for (int i /*hier müsste man die Adresse von i ermitteln*/; ; )
{
}
</code></pre>
<p>Das ist mir ein Rätsel (wie das meiste in boost).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1802360</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1802360</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Mon, 02 Nov 2009 20:27:02 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionsweise von boost::foreach und typeof on Tue, 03 Nov 2009 20:20:13 GMT]]></title><description><![CDATA[<p>TyRoXx schrieb:</p>
<blockquote>
<pre><code class="language-cpp">for (int i /*hier müsste man die Adresse von i ermitteln*/; ; )
</code></pre>
</blockquote>
<p>Nein, muss man nicht. Die Variable <code>i</code> ist schliesslich nur die Laufvariable, sozusagen die Schnittstelle zum Code im Schleifenrumpf. Als Benutzer ist eine Möglichkeit erforderlich, um das Objekt ansprechen können, über das gerade iteriert wird.</p>
<p>Für die Implementierung von <code>BOOST_FOREACH</code> ist der erste Parameter nicht wirklich wichtig. Ihm wird ein Wert zugewiesen, der zuerst den Anfang des Containers (Makro-Argument <code>COL</code> ) repräsentiert. Danach wird er aktualisiert. Wie du siehst, passiert das in einer weiteren Schleife, sodass <code>VAR</code> gleich initialisiert wird (ist z.B. zwingend notwendig bei Referenzen).</p>
<p>Originalcode (Boost 1.36, Datei boost/foreach.hpp):</p>
<pre><code class="language-cpp">#define BOOST_FOREACH(VAR, COL)                                                                 \
    BOOST_FOREACH_PREAMBLE()                                                                    \
    if (boost::foreach_detail_::auto_any_t _foreach_col = BOOST_FOREACH_CONTAIN(COL)) {} else   \
    if (boost::foreach_detail_::auto_any_t _foreach_cur = BOOST_FOREACH_BEGIN(COL)) {} else     \
    if (boost::foreach_detail_::auto_any_t _foreach_end = BOOST_FOREACH_END(COL)) {} else       \
    for (bool _foreach_continue = true;                                                         \
              _foreach_continue &amp;&amp; !BOOST_FOREACH_DONE(COL);                                    \
              _foreach_continue ? BOOST_FOREACH_NEXT(COL) : (void)0)                            \
        if  (boost::foreach_detail_::set_false(_foreach_continue)) {} else                      \
        for (VAR = BOOST_FOREACH_DEREF(COL); !_foreach_continue; _foreach_continue = true)
</code></pre>
<p>Hinter <code>BOOST_FOREACH</code> steckt - wie bei vielen Dingen in Boost - in der Tat ein genialer Mechanismus. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f4a1.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--light_bulb"
      title=":bulb:"
      alt="💡"
    /></p>
<p><em>Edit: Richtigen Code eingefügt</em></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1802377</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1802377</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Tue, 03 Nov 2009 20:20:13 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionsweise von boost::foreach und typeof on Tue, 03 Nov 2009 10:18:36 GMT]]></title><description><![CDATA[<p>Nexus, du hast aber den Code für &quot;BOOST_REVERSE_FOREACH&quot; gepostet -)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1802577</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1802577</guid><dc:creator><![CDATA[Th69]]></dc:creator><pubDate>Tue, 03 Nov 2009 10:18:36 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionsweise von boost::foreach und typeof on Tue, 03 Nov 2009 17:13:19 GMT]]></title><description><![CDATA[<p>Danke für die Hilfe, jetzt habe ichs hinbekommen:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;boost/typeof/typeof.hpp&gt;
using namespace std;

#define foreach(ele, arr) \
	for (BOOST_TYPEOF(arr[0]) *foreach_parr = arr, \
		*foreach_end = arr + (sizeof(arr)/sizeof(arr[0])); \
		foreach_parr != foreach_end; ++foreach_parr) \
		for (bool foreach_continue = true; foreach_continue; ) \
			for (ele = *foreach_parr; foreach_continue; foreach_continue = false)

int main()
{
	int values[] = {1, 2, 3, 8, 4, 2};

	foreach(int i, values)
	{
		cout &lt;&lt; i &lt;&lt; endl;
	}
	cin.get();
    return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1802787</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1802787</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Tue, 03 Nov 2009 17:13:19 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionsweise von boost::foreach und typeof on Tue, 03 Nov 2009 20:24:49 GMT]]></title><description><![CDATA[<p>Th69 schrieb:</p>
<blockquote>
<p>Nexus, du hast aber den Code für &quot;BOOST_REVERSE_FOREACH&quot; gepostet -)</p>
</blockquote>
<p>Verdammt! Ich war ein wenig in der Headerdatei am stöbern, da habe ich wohl aus Versehen das falsche Makro kopiert. Aber das Prinzip ist natürlich das Gleiche. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /><br />
Ich habs trotzdem mal korrigiert.</p>
<p>TyRoXx schrieb:</p>
<blockquote>
<p>Danke für die Hilfe, jetzt habe ichs hinbekommen:</p>
</blockquote>
<p>Nicht schlecht! Allerdings fehlt mir die Anbindung an Container, was ich als zentralen Einsatzzweck von <code>BOOST_FOREACH</code> ansehe. :p</p>
<p>Nein, gut, dass du das hingekriegt hast! In C++0x wäre so ein Makro wie schon erwähnt recht elegant möglich, <a href="http://www.c-plusplus.net/forum/viewtopic-var-t-is-245794.html" rel="nofollow">hier</a> gab es einen Thread dazu.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1802875</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1802875</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Tue, 03 Nov 2009 20:24:49 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionsweise von boost::foreach und typeof on Wed, 04 Nov 2009 01:49:35 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/12954">@Nexus</a>/TyRoXx:<br />
Nicht nur fehlt die Anbindung an Container, auch wird hier BOOST_TYPEOF verwendet (was nicht nötig ist), und &quot;arr&quot; mehrfach ausgewertet.</p>
<p>Beides &quot;richtig&quot; zu machen ist allerdings ziemlich viel Aufwand. Sieht man ja wie schnell das ausartet, wenn man sich den Original Boost Code ansieht.</p>
<p>Einer der coolsten Tricks aus der Boost Implementierung:</p>
<pre><code class="language-cpp">// A sneaky way to get the type of the collection without evaluating the expression
#define BOOST_FOREACH_TYPEOF(COL)                                                               \
    (true ? 0 : boost::foreach_detail_::encode_type(COL, boost::foreach_detail_::is_const_(COL)))
</code></pre>
<p>Wunderbar <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/1802978</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1802978</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 04 Nov 2009 01:49:35 GMT</pubDate></item></channel></rss>