<?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[Typelist &#x2F; Code Generierung &#x2F; Findet falsche Funktion]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>Während ich gerade Modern C++ Design lese, kommen mir allerhand Ideen, welche ich auch ausprobiere. Absolut geiles Buch!<br />
Bei einer dieser Ideen ist mir ein Fehler an den Kopf geworfen worden, den ich schlicht und einfach nicht verstehe und gespannt bin, ob mir jemand diesen Fehler erklären kann.</p>
<p>Ich verwende hier verschiedene Konstrukte aus der Loki-Bibliothek, bzw. entsprechend Nachgebaute und werde diese somit nicht hier nochmals aufführen und nur meinen Code reinsetzen.</p>
<p>Die Idee war eine Art von Event-System aufzubauen, welches über eine Typelist generiert wird.</p>
<p><strong>EventListener.hpp</strong></p>
<pre><code class="language-cpp">//////////////////////////////////////////////////////////////////////////
// EventListener : Header file

#ifndef EVENT_H_EVENT_LISTENER_GUARD__
#define EVENT_H_EVENT_LISTENER_GUARD__

#include &quot;Typelist.hpp&quot;

template&lt;typename ListT&gt;
class EventListener;

template&lt;&gt;
class EventListener&lt;util::NullType&gt;
{
};

template&lt;typename HeadT, typename TailT&gt;
class EventListener&lt;tl::Typelist&lt;HeadT, TailT&gt; &gt;
	: public EventListener&lt;TailT&gt;
{
protected:
	virtual void on_event(HeadT&amp;) = 0;
};

#endif // EVENT_H_EVENT_LISTENER_GUARD__
</code></pre>
<p><strong>EventConsumer.hpp</strong></p>
<pre><code class="language-cpp">//////////////////////////////////////////////////////////////////////////
// EventConsumer : Header file

#ifndef EVENT_H_EVENT_CONSUMER_GUARD__
#define EVENT_H_EVENT_CONSUMER_GUARD__

#include &quot;Typelist.hpp&quot;
#include &quot;EventListener.hpp&quot;

template&lt;typename EventListT&gt;
class EventConsumer
	: public EventListener&lt;EventListT&gt;
{
private:
	typedef EventListT EventList;

	template&lt;typename EventT&gt;
	void handle_event(EventT&amp; evt, util::Int2Type&lt;true&gt;)
	{
		on_event(evt);
	}

	template&lt;typename EventT&gt;
	void handle_event(EventT&amp; evt, util::Int2Type&lt;false&gt;)
	{
	}

public:
	template&lt;typename EventT&gt;
	void handle_event(EventT&amp; evt)
	{
		static bool const DO_SELECT
			= tl::IndexOf&lt;EventList, EventT&gt;::RESULT &gt;= 0;

		handle_event(
			evt,
			util::Select
			&lt;
				DO_SELECT,
				util::Int2Type&lt;true&gt;,
				util::Int2Type&lt;false&gt;
			&gt;::Result());
	}
};

#endif // EVENT_H_EVENT_CONSUMER_GUARD__
</code></pre>
<p><strong>main.cpp</strong></p>
<pre><code class="language-cpp">//////////////////////////////////////////////////////////////////////////
// main : Implementation file

#include &quot;Typelist.hpp&quot;

#include &quot;EventConsumer.hpp&quot;

#include &lt;string&gt;
#include &lt;iostream&gt;

class TestWidget
	: public EventConsumer&lt;M_TYPELIST_3(int, std::string, char)&gt;
{
protected:
	virtual void on_event(int&amp;)
	{
		std::cout &lt;&lt; &quot;int&quot; &lt;&lt; std::endl;
	}

	virtual void on_event(std::string&amp;)
	{
		std::cout &lt;&lt; &quot;string&quot; &lt;&lt; std::endl;
	}

	virtual void on_event(char&amp;)
	{
		std::cout &lt;&lt; &quot;char&quot; &lt;&lt; std::endl;
	}
};

int main()
{
	using namespace tl;

	TestWidget widget;

	int x;
	std::string l;
	char s;

	widget.handle_event(x);
	widget.handle_event(s);
	widget.handle_event(l);

	std::cin.get();

	return 0;
}
</code></pre>
<p>Ergibt die zwei Fehler:</p>
<pre><code>1&gt;c:\...\eventconsumer.hpp(20) : error C2664: 'EventListener&lt;ListT&gt;::on_event' : cannot convert parameter 1 from 'char' to 'int &amp;'
1&gt;        with
1&gt;        [
1&gt;            ListT=tl::Typelist&lt;int,tl::Typelist&lt;std::string,tl::Typelist&lt;char&gt;&gt;&gt;
1&gt;        ]
1&gt;        c:\...\eventconsumer.hpp(42) : see reference to function template instantiation 'void EventConsumer&lt;EventListT&gt;::handle_event&lt;EventT&gt;(EventT &amp;,util::Int2Type&lt;V&gt;)' being compiled
1&gt;        with
1&gt;        [
1&gt;            EventListT=tl::Typelist&lt;int,tl::Typelist&lt;std::string,tl::Typelist&lt;char&gt;&gt;&gt;,
1&gt;            EventT=char,
1&gt;            V=1
1&gt;        ]
1&gt;        c:\...\main.cpp(44) : see reference to function template instantiation 'void EventConsumer&lt;EventListT&gt;::handle_event&lt;char&gt;(EventT &amp;)' being compiled
1&gt;        with
1&gt;        [
1&gt;            EventListT=tl::Typelist&lt;int,tl::Typelist&lt;std::string,tl::Typelist&lt;char&gt;&gt;&gt;,
1&gt;            EventT=char
1&gt;        ]
1&gt;c:\...\eventconsumer.hpp(20) : error C2664: 'EventListener&lt;ListT&gt;::on_event' : cannot convert parameter 1 from 'std::string' to 'int &amp;'
1&gt;        with
1&gt;        [
1&gt;            ListT=tl::Typelist&lt;int,tl::Typelist&lt;std::string,tl::Typelist&lt;char&gt;&gt;&gt;
1&gt;        ]
1&gt;        c:\...\eventconsumer.hpp(42) : see reference to function template instantiation 'void EventConsumer&lt;EventListT&gt;::handle_event&lt;EventT&gt;(EventT &amp;,util::Int2Type&lt;V&gt;)' being compiled
1&gt;        with
1&gt;        [
1&gt;            EventListT=tl::Typelist&lt;int,tl::Typelist&lt;std::string,tl::Typelist&lt;char&gt;&gt;&gt;,
1&gt;            EventT=std::string,
1&gt;            V=1
1&gt;        ]
1&gt;        c:\...\main.cpp(45) : see reference to function template instantiation 'void EventConsumer&lt;EventListT&gt;::handle_event&lt;std::string&gt;(EventT &amp;)' being compiled
1&gt;        with
1&gt;        [
1&gt;            EventListT=tl::Typelist&lt;int,tl::Typelist&lt;std::string,tl::Typelist&lt;char&gt;&gt;&gt;,
1&gt;            EventT=std::string
1&gt;        ]
</code></pre>
<p>Ich hoffe das ist nicht zu viel Code, aber ich glaube kaum, dass man das deutlich minimieren kann, um zu verstehen, was hier passiert.</p>
<p>Eine Lösung habe ich zwar gefunden, in dem ich EventListener ein wenig umgebaut habe, so dass ich direkt eine nicht virtuelle Funktion im richtigen EventListener aufrufen kann. Diese nicht virtuelle Funktion leitet den Event dann weiter an die virtuelle Funktion. Ist allerdings etwas umständlich, wie ich finde. Es wäre schöner, wenn die obige Lösung funktionieren würde <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>Ich hoffe jemand kann sich die Zeit nehmen und mir helfen. Bei Fragen fragen!</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/234275/typelist-code-generierung-findet-falsche-funktion</link><generator>RSS for Node</generator><lastBuildDate>Thu, 24 Sep 2026 11:00:47 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/234275.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 15 Feb 2009 20:53:24 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Typelist &#x2F; Code Generierung &#x2F; Findet falsche Funktion on Sun, 15 Feb 2009 20:53:24 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>Während ich gerade Modern C++ Design lese, kommen mir allerhand Ideen, welche ich auch ausprobiere. Absolut geiles Buch!<br />
Bei einer dieser Ideen ist mir ein Fehler an den Kopf geworfen worden, den ich schlicht und einfach nicht verstehe und gespannt bin, ob mir jemand diesen Fehler erklären kann.</p>
<p>Ich verwende hier verschiedene Konstrukte aus der Loki-Bibliothek, bzw. entsprechend Nachgebaute und werde diese somit nicht hier nochmals aufführen und nur meinen Code reinsetzen.</p>
<p>Die Idee war eine Art von Event-System aufzubauen, welches über eine Typelist generiert wird.</p>
<p><strong>EventListener.hpp</strong></p>
<pre><code class="language-cpp">//////////////////////////////////////////////////////////////////////////
// EventListener : Header file

#ifndef EVENT_H_EVENT_LISTENER_GUARD__
#define EVENT_H_EVENT_LISTENER_GUARD__

#include &quot;Typelist.hpp&quot;

template&lt;typename ListT&gt;
class EventListener;

template&lt;&gt;
class EventListener&lt;util::NullType&gt;
{
};

template&lt;typename HeadT, typename TailT&gt;
class EventListener&lt;tl::Typelist&lt;HeadT, TailT&gt; &gt;
	: public EventListener&lt;TailT&gt;
{
protected:
	virtual void on_event(HeadT&amp;) = 0;
};

#endif // EVENT_H_EVENT_LISTENER_GUARD__
</code></pre>
<p><strong>EventConsumer.hpp</strong></p>
<pre><code class="language-cpp">//////////////////////////////////////////////////////////////////////////
// EventConsumer : Header file

#ifndef EVENT_H_EVENT_CONSUMER_GUARD__
#define EVENT_H_EVENT_CONSUMER_GUARD__

#include &quot;Typelist.hpp&quot;
#include &quot;EventListener.hpp&quot;

template&lt;typename EventListT&gt;
class EventConsumer
	: public EventListener&lt;EventListT&gt;
{
private:
	typedef EventListT EventList;

	template&lt;typename EventT&gt;
	void handle_event(EventT&amp; evt, util::Int2Type&lt;true&gt;)
	{
		on_event(evt);
	}

	template&lt;typename EventT&gt;
	void handle_event(EventT&amp; evt, util::Int2Type&lt;false&gt;)
	{
	}

public:
	template&lt;typename EventT&gt;
	void handle_event(EventT&amp; evt)
	{
		static bool const DO_SELECT
			= tl::IndexOf&lt;EventList, EventT&gt;::RESULT &gt;= 0;

		handle_event(
			evt,
			util::Select
			&lt;
				DO_SELECT,
				util::Int2Type&lt;true&gt;,
				util::Int2Type&lt;false&gt;
			&gt;::Result());
	}
};

#endif // EVENT_H_EVENT_CONSUMER_GUARD__
</code></pre>
<p><strong>main.cpp</strong></p>
<pre><code class="language-cpp">//////////////////////////////////////////////////////////////////////////
// main : Implementation file

#include &quot;Typelist.hpp&quot;

#include &quot;EventConsumer.hpp&quot;

#include &lt;string&gt;
#include &lt;iostream&gt;

class TestWidget
	: public EventConsumer&lt;M_TYPELIST_3(int, std::string, char)&gt;
{
protected:
	virtual void on_event(int&amp;)
	{
		std::cout &lt;&lt; &quot;int&quot; &lt;&lt; std::endl;
	}

	virtual void on_event(std::string&amp;)
	{
		std::cout &lt;&lt; &quot;string&quot; &lt;&lt; std::endl;
	}

	virtual void on_event(char&amp;)
	{
		std::cout &lt;&lt; &quot;char&quot; &lt;&lt; std::endl;
	}
};

int main()
{
	using namespace tl;

	TestWidget widget;

	int x;
	std::string l;
	char s;

	widget.handle_event(x);
	widget.handle_event(s);
	widget.handle_event(l);

	std::cin.get();

	return 0;
}
</code></pre>
<p>Ergibt die zwei Fehler:</p>
<pre><code>1&gt;c:\...\eventconsumer.hpp(20) : error C2664: 'EventListener&lt;ListT&gt;::on_event' : cannot convert parameter 1 from 'char' to 'int &amp;'
1&gt;        with
1&gt;        [
1&gt;            ListT=tl::Typelist&lt;int,tl::Typelist&lt;std::string,tl::Typelist&lt;char&gt;&gt;&gt;
1&gt;        ]
1&gt;        c:\...\eventconsumer.hpp(42) : see reference to function template instantiation 'void EventConsumer&lt;EventListT&gt;::handle_event&lt;EventT&gt;(EventT &amp;,util::Int2Type&lt;V&gt;)' being compiled
1&gt;        with
1&gt;        [
1&gt;            EventListT=tl::Typelist&lt;int,tl::Typelist&lt;std::string,tl::Typelist&lt;char&gt;&gt;&gt;,
1&gt;            EventT=char,
1&gt;            V=1
1&gt;        ]
1&gt;        c:\...\main.cpp(44) : see reference to function template instantiation 'void EventConsumer&lt;EventListT&gt;::handle_event&lt;char&gt;(EventT &amp;)' being compiled
1&gt;        with
1&gt;        [
1&gt;            EventListT=tl::Typelist&lt;int,tl::Typelist&lt;std::string,tl::Typelist&lt;char&gt;&gt;&gt;,
1&gt;            EventT=char
1&gt;        ]
1&gt;c:\...\eventconsumer.hpp(20) : error C2664: 'EventListener&lt;ListT&gt;::on_event' : cannot convert parameter 1 from 'std::string' to 'int &amp;'
1&gt;        with
1&gt;        [
1&gt;            ListT=tl::Typelist&lt;int,tl::Typelist&lt;std::string,tl::Typelist&lt;char&gt;&gt;&gt;
1&gt;        ]
1&gt;        c:\...\eventconsumer.hpp(42) : see reference to function template instantiation 'void EventConsumer&lt;EventListT&gt;::handle_event&lt;EventT&gt;(EventT &amp;,util::Int2Type&lt;V&gt;)' being compiled
1&gt;        with
1&gt;        [
1&gt;            EventListT=tl::Typelist&lt;int,tl::Typelist&lt;std::string,tl::Typelist&lt;char&gt;&gt;&gt;,
1&gt;            EventT=std::string,
1&gt;            V=1
1&gt;        ]
1&gt;        c:\...\main.cpp(45) : see reference to function template instantiation 'void EventConsumer&lt;EventListT&gt;::handle_event&lt;std::string&gt;(EventT &amp;)' being compiled
1&gt;        with
1&gt;        [
1&gt;            EventListT=tl::Typelist&lt;int,tl::Typelist&lt;std::string,tl::Typelist&lt;char&gt;&gt;&gt;,
1&gt;            EventT=std::string
1&gt;        ]
</code></pre>
<p>Ich hoffe das ist nicht zu viel Code, aber ich glaube kaum, dass man das deutlich minimieren kann, um zu verstehen, was hier passiert.</p>
<p>Eine Lösung habe ich zwar gefunden, in dem ich EventListener ein wenig umgebaut habe, so dass ich direkt eine nicht virtuelle Funktion im richtigen EventListener aufrufen kann. Diese nicht virtuelle Funktion leitet den Event dann weiter an die virtuelle Funktion. Ist allerdings etwas umständlich, wie ich finde. Es wäre schöner, wenn die obige Lösung funktionieren würde <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>Ich hoffe jemand kann sich die Zeit nehmen und mir helfen. Bei Fragen fragen!</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1664433</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1664433</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Sun, 15 Feb 2009 20:53:24 GMT</pubDate></item><item><title><![CDATA[Reply to Typelist &#x2F; Code Generierung &#x2F; Findet falsche Funktion on Sun, 15 Feb 2009 22:18:04 GMT]]></title><description><![CDATA[<p>Ist wirklich komisch. Wenn man on_event public macht und dann von außen aufruft, so funktioniert es - innerhalb der Template-Methode nicht. Es nützt auch nichts, wenn man in EventConsumer alle Methoden konkret hinschreibt (was natürlich nicht im Sinne des Erfinders ist, aber so als Test)</p>
<p>Was für einen Compiler benutzt Du? Ich habe mit VC9 express genau das von Dir beschriebene Verhalten.</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1664455</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1664455</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Sun, 15 Feb 2009 22:18:04 GMT</pubDate></item><item><title><![CDATA[Reply to Typelist &#x2F; Code Generierung &#x2F; Findet falsche Funktion on Sun, 15 Feb 2009 22:39:23 GMT]]></title><description><![CDATA[<p>VC9 SP1 Team Suite, also wohl den gleichen Kompiler wie du.<br />
In der Theorie sollte die Funktion aber gefunden werden, oder? Also ist das ein Kompilerfehler?</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1664459</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1664459</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Sun, 15 Feb 2009 22:39:23 GMT</pubDate></item><item><title><![CDATA[Reply to Typelist &#x2F; Code Generierung &#x2F; Findet falsche Funktion on Sun, 15 Feb 2009 23:09:05 GMT]]></title><description><![CDATA[<p>Ist doch logisch, eine Elternklasse kann doch nicht die Methoden des Kinds aufrufen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
<p>edit: Upsi, hab die Klasse EventListener glatt übersehen... <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/1664467</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1664467</guid><dc:creator><![CDATA[Badestrand]]></dc:creator><pubDate>Sun, 15 Feb 2009 23:09:05 GMT</pubDate></item><item><title><![CDATA[Reply to Typelist &#x2F; Code Generierung &#x2F; Findet falsche Funktion on Tue, 17 Feb 2009 01:18:50 GMT]]></title><description><![CDATA[<p>Jemand noch eine Idee? Kann das vielleicht jemand mit einem anderen Kompiler testen? Ansonsten auch nicht so wichtig, wäre vielleicht höchstens für ein Bug-Report an Microsoft interessant, falls dies wirklich ein Bug ist.</p>
<p>Danke für die Mühen.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1665053</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1665053</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Tue, 17 Feb 2009 01:18:50 GMT</pubDate></item><item><title><![CDATA[Reply to Typelist &#x2F; Code Generierung &#x2F; Findet falsche Funktion on Tue, 17 Feb 2009 02:05:33 GMT]]></title><description><![CDATA[<p>Badestrand schrieb:</p>
<blockquote>
<p>Ist doch logisch, eine Elternklasse kann doch nicht die Methoden des Kinds aufrufen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
</blockquote>
<p>Mit CRTP geht das 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="🙂"
    /><br />
<a href="http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern" rel="nofollow">http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1665055</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1665055</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 17 Feb 2009 02:05:33 GMT</pubDate></item><item><title><![CDATA[Reply to Typelist &#x2F; Code Generierung &#x2F; Findet falsche Funktion on Tue, 17 Feb 2009 12:11:10 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">template&lt;typename HeadT, typename TailT&gt;
class EventListener&lt;tl::Typelist&lt;HeadT, TailT&gt; &gt;
    : public EventListener&lt;TailT&gt;
{
protected:
    virtual void on_event(HeadT&amp;) = 0;
};
</code></pre>
<p>Das Problem ist hier die Vererbung. Du versucht über Vererbung zu überladen. Bei der ersten Instanzierung hast du ein on_event(int&amp;) und versucht durch die Vererbung weitere reinzuholen, doch das lokale, also das erste on_event(int&amp;) überdeckt die anderen.</p>
<p>Überladen funktioniert nicht über Klassen hinweg. Das endet immer bei Überdeckung ...</p>
<p>Edit: Dies ist auch der Grund für deine Fehlermeldung. Der Compiler kennt nur das on_event für int&amp;.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1665225</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1665225</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Tue, 17 Feb 2009 12:11:10 GMT</pubDate></item><item><title><![CDATA[Reply to Typelist &#x2F; Code Generierung &#x2F; Findet falsche Funktion on Tue, 17 Feb 2009 15:00:26 GMT]]></title><description><![CDATA[<p>@KasF,<br />
Stimmt, habe es inzwischen auch im Standard 98 gefunden:<br />
13.2 Abschnitt 1<br />
Überladung geht nur, wenn die Funktionen im selben &quot;Scope&quot; sind. Eine Memberfunktion in einer Elternklasse ist nicht im gleichen &quot;Scope&quot; wie eine Memberfunktion in einer Kindklasse.</p>
<p>Mist.</p>
<p>Dann ist meine zweite Lösung, welche ich hinbekommen habe, doch die einzige Möglichkeit. Ich füge sie nur zur Vollständigkeit noch dazu:</p>
<p><strong>EventListener.hpp</strong></p>
<pre><code class="language-cpp">//////////////////////////////////////////////////////////////////////////
// EventListener : Header file

#ifndef EVENT_H_EVENT_LISTENER_GUARD__
#define EVENT_H_EVENT_LISTENER_GUARD__

#include &quot;Typelist.hpp&quot;

template&lt;typename EventT&gt;
class EventListener
{
protected:
	virtual void on_event(EventT&amp;) = 0;

	void on_event(EventT&amp; evt, util::Type2Type&lt;EventT&gt;)
	{
		on_event(evt);
	}
};

template&lt;typename ListT&gt;
class EventListenerCreator;

template&lt;&gt;
class EventListenerCreator&lt;util::NullType&gt;
{
};

template&lt;typename HeadT, typename TailT&gt;
class EventListenerCreator&lt;tl::Typelist&lt;HeadT, TailT&gt; &gt;
	: public EventListenerCreator&lt;TailT&gt;
	, public EventListener&lt;HeadT&gt;
{
};

#endif // EVENT_H_EVENT_LISTENER_GUARD__
</code></pre>
<pre><code class="language-cpp">//////////////////////////////////////////////////////////////////////////
// EventConsumer : Header file

#ifndef EVENT_H_EVENT_CONSUMER_GUARD__
#define EVENT_H_EVENT_CONSUMER_GUARD__

#include &quot;Typelist.hpp&quot;
#include &quot;EventListener.hpp&quot;

template&lt;typename EventListT&gt;
class EventConsumer
	: public EventListenerCreator&lt;EventListT&gt;
{
private:
	typedef EventListT EventList;

	template&lt;typename EventT&gt;
	void handle_event(EventT&amp; evt, util::Int2Type&lt;true&gt;)
	{
		EventListener&lt;EventT&gt;::on_event(evt, util::Type2Type&lt;EventT&gt;());
	}

	template&lt;typename EventT&gt;
	void handle_event(EventT&amp; evt, util::Int2Type&lt;false&gt;)
	{
	}

public:
	template&lt;typename EventT&gt;
	void handle_event(EventT&amp; evt)
	{
		static bool const DO_SELECT
			= tl::IndexOf&lt;EventList, EventT&gt;::RESULT &gt;= 0;

		handle_event(
			evt,
			util::Select
			&lt;
				DO_SELECT,
				util::Int2Type&lt;true&gt;,
				util::Int2Type&lt;false&gt;
			&gt;::Result());
	}
};

#endif // EVENT_H_EVENT_CONSUMER_GUARD__
</code></pre>
<p>Wichtige Unterschiede:</p>
<ul>
<li><code>EventListener</code> ist ein Klassentemplate, welches als Templateparameter nur den entsprechenden Eventtyp erwartet. Dadurch ist es leicht die richtige Basisklasse anzusprechen.</li>
<li><code>EventListenerCreator</code> ist nun zuständige für die Erstellung der Hierarchie.</li>
<li><code>EventConsumer::handle_event(EventT, util::Int2Type&lt;true&gt;)</code> leitet den Event zuerst in den richtigen Scope um, damit die Überladung funktioniert.</li>
</ul>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1665320</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1665320</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Tue, 17 Feb 2009 15:00:26 GMT</pubDate></item></channel></rss>