<?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[Problem mit Vector von Funktoren]]></title><description><![CDATA[<p>Ich hätte gerne einen Vektor von Funktoren, die aber jeweils auf unterschiedliche Memberfunktionen von unterschiedlichen Klassen zeigen können bzw. evtl auch auf eine normale Funktion. Bedingung dabei ist natürlich, dass Rückgabewert und Parameterliste jeweils gleich ist. Hier erstmal mein Testcode:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;vector&gt;

void test() {
	std::cout &lt;&lt; &quot;test()&quot; &lt;&lt; std::endl;
}

class Test {
	public:
		void test() {
			std::cout &lt;&lt; &quot;Test::test()&quot; &lt;&lt; std::endl;
		}
};

class Test2 {
	public:
		void test() {
			std::cout &lt;&lt; &quot;Test2::test()&quot; &lt;&lt; std::endl;
		}
};

class Functor {
	public:
		Functor(void (* _func)()) : Object(0), Fun(_func) {}
		template&lt;class C&gt;
		Functor(C* _o, void (C::* _m)()) : Object(_o) {}

		void operator()() {
			if (!Object) {  // normal function
				Fun();
			}
			else {  // call object's memberfunction
			}
		}

	private:
		void* Object;
		void (* Fun)();
};

int main() {
	Test  t;
	Test2 t2;

	std::vector&lt;Functor&gt; vec;
	vec.push_back( Functor(&amp;test) );
	vec.push_back( Functor(&amp;t, &amp;Test::test) );
	vec.push_back( Functor(&amp;t2, &amp;Test2::test) );

	for (int i = 0; i &lt; vec.size(); i++) {
		vec[i]();
	}

	return 0;
}
</code></pre>
<p>So ungefähr hätte ich es gerne, wenn es denn möglich ist. Mein Problem ist, dass ich nicht weiß, wie ich den Zeiger auf die Memberfunktion in den Funktor bekomme und als nächstes wie ich diese dann mit dem Zeiger auf das Objekt aufrufe.</p>
<p>Ich habe es hier jetzt mal versucht nur den Konstruktor des Funktors als Template zu realisieren, da ich ansonsten das Problem habe, dass ich die Template-Parameter bei der Definition des Vektors angeben muss und ich somit nicht Memberfunktionen von verschiedenen Klassen in dem Vektor speichern kann (und normale Funktionen würde wegfallen, was aber nicht sooo tragisch wäre). Einzige Möglichkeit wäre hier dann (soweit ich weiß) den Functor vom Typen einer Basisklasse zu nehmen und in der Zuweisung auf die Basisklasse zu casten, was aber voraussetzen würde, dass alle Memberfunktionen von Klassen sind, die von einer Basisklasse abgeleitet werden, was ich aber nicht will.</p>
<p>Hat da jmd. eine Idee?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/140214/problem-mit-vector-von-funktoren</link><generator>RSS for Node</generator><lastBuildDate>Sun, 30 Aug 2026 23:14:51 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/140214.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 13 Mar 2006 10:16:09 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Problem mit Vector von Funktoren on Mon, 13 Mar 2006 10:16:09 GMT]]></title><description><![CDATA[<p>Ich hätte gerne einen Vektor von Funktoren, die aber jeweils auf unterschiedliche Memberfunktionen von unterschiedlichen Klassen zeigen können bzw. evtl auch auf eine normale Funktion. Bedingung dabei ist natürlich, dass Rückgabewert und Parameterliste jeweils gleich ist. Hier erstmal mein Testcode:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;vector&gt;

void test() {
	std::cout &lt;&lt; &quot;test()&quot; &lt;&lt; std::endl;
}

class Test {
	public:
		void test() {
			std::cout &lt;&lt; &quot;Test::test()&quot; &lt;&lt; std::endl;
		}
};

class Test2 {
	public:
		void test() {
			std::cout &lt;&lt; &quot;Test2::test()&quot; &lt;&lt; std::endl;
		}
};

class Functor {
	public:
		Functor(void (* _func)()) : Object(0), Fun(_func) {}
		template&lt;class C&gt;
		Functor(C* _o, void (C::* _m)()) : Object(_o) {}

		void operator()() {
			if (!Object) {  // normal function
				Fun();
			}
			else {  // call object's memberfunction
			}
		}

	private:
		void* Object;
		void (* Fun)();
};

int main() {
	Test  t;
	Test2 t2;

	std::vector&lt;Functor&gt; vec;
	vec.push_back( Functor(&amp;test) );
	vec.push_back( Functor(&amp;t, &amp;Test::test) );
	vec.push_back( Functor(&amp;t2, &amp;Test2::test) );

	for (int i = 0; i &lt; vec.size(); i++) {
		vec[i]();
	}

	return 0;
}
</code></pre>
<p>So ungefähr hätte ich es gerne, wenn es denn möglich ist. Mein Problem ist, dass ich nicht weiß, wie ich den Zeiger auf die Memberfunktion in den Funktor bekomme und als nächstes wie ich diese dann mit dem Zeiger auf das Objekt aufrufe.</p>
<p>Ich habe es hier jetzt mal versucht nur den Konstruktor des Funktors als Template zu realisieren, da ich ansonsten das Problem habe, dass ich die Template-Parameter bei der Definition des Vektors angeben muss und ich somit nicht Memberfunktionen von verschiedenen Klassen in dem Vektor speichern kann (und normale Funktionen würde wegfallen, was aber nicht sooo tragisch wäre). Einzige Möglichkeit wäre hier dann (soweit ich weiß) den Functor vom Typen einer Basisklasse zu nehmen und in der Zuweisung auf die Basisklasse zu casten, was aber voraussetzen würde, dass alle Memberfunktionen von Klassen sind, die von einer Basisklasse abgeleitet werden, was ich aber nicht will.</p>
<p>Hat da jmd. eine Idee?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1015099</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1015099</guid><dc:creator><![CDATA[mantiz]]></dc:creator><pubDate>Mon, 13 Mar 2006 10:16:09 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Vector von Funktoren on Mon, 13 Mar 2006 10:26:28 GMT]]></title><description><![CDATA[<p>Erstmal kannst du eine &quot;normale&quot; Funktion und eine Memberfunktion nicht in den selben Typ speichern (letztere müsstest du in (C::*)() (oder so ähnlich) speichern) und zweitens weiß ich nicht einmal, ob deine Designidee überhaupt realisierbar ist - Wozu soll das überhaupt sinnvoll sein?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1015112</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1015112</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Mon, 13 Mar 2006 10:26:28 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Vector von Funktoren on Mon, 13 Mar 2006 10:42:39 GMT]]></title><description><![CDATA[<p>Das ganze soll mir als Callback-Mechanismuns dienen. Ich möchte z.B. eine Klasse haben:</p>
<pre><code class="language-cpp">class EventHandler {
    public:
        enum EventType {
            onSize,
            onClose,
        };
        void addListener(EventType _e, Functor _f) {
            EventTable[_e].push_back(_f);
        }
        void notifyListener(EventType _e) {
            for (int i = 0; i &lt; EventTable[_e].size(); i++) {
                EventTable[_e][i]();
            }
        }
    private:
        std::map&lt; EventType, std::vector&lt;Functor&gt; &gt; EventTable;
};
</code></pre>
<p>also so in der Art.</p>
<p>Zur weiteren Erläuterung:<br />
Ich bastle für mich zu Lernzwecken an einem kleinen GUI-Toolkit, womit ich mir einige Dinge klarmachen möchte.</p>
<p>Bisher habe ich das so gelöst, dass ich die Klasse Functor komplett als Template realisiert habe und auf eine Basisklasse caste, wie gesagt möchte ich das aber nicht mehr. Es soll egal sein, was das für eine Klasse ist, dessen Memberfunktion aufgerufen werden soll.</p>
<p>Ein Lösung, die mir folgendes erlauben würde wäre auch schön:</p>
<pre><code class="language-cpp">Klasse1 k;
Klasse2 k2;
std::vector&lt; Functor&lt;Klasse1&gt; &gt; vec;
vec.push_back( Functor(&amp;k, &amp;Klasse1::test) );
vec.push_back( Functor(&amp;k2, &amp;Klasse2::test) );
</code></pre>
<p>Problem hierbei ist allerdings, dass mir beim zweiten push_back eine Meldung ausgeworfen wird, dass die Methode push_back für Klasse2 nicht existiert, was auch klar ist, weil ich den Vektor ja als Funktor von Klasse1 erstellt habe.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1015127</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1015127</guid><dc:creator><![CDATA[mantiz]]></dc:creator><pubDate>Mon, 13 Mar 2006 10:42:39 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Vector von Funktoren on Mon, 13 Mar 2006 10:52:15 GMT]]></title><description><![CDATA[<p>Ich glaube, da kommst du um deine Lösung nicht herum - eventuell noch mit ein paar Hilfsfunktionen drumherum:</p>
<pre><code class="language-cpp">class callback
{
public:
  virtual void call() = 0;
  virtual ~callback() {}
}

template&lt;typename T&gt;
class mem_caller_t : public callback
{
public:
  mem_caller_t(T&amp; ob, void (T::*mem)()) : m_ob(ob),m_mem(mem) {}
  void call()
  { m_ob.*m_mem(); }
private:
  T&amp; m_ob;
  void (T::*m_mem)();
}
template&lt;typename T&gt;
mem_caller_t* mem_caller(T&amp; ob,void(T::*mem)())
{ return new mem_caller_t(ob,mem); }

...
vector&lt;callback*&gt; vec;
vec.push_back(mem_caller(k1,&amp;Klasse1::test));
vec.push_back(mem_caller(k2,&amp;Klasse2::print));
...
for(int i=0;i&lt;vec.size();++i)
  vec[i]-&gt;call();
</code></pre>
<p>(und mit einer zweiten Klasse glob_caller_t kannst du dort sogar normale Funktionen integrieren)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1015140</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1015140</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Mon, 13 Mar 2006 10:52:15 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Vector von Funktoren on Mon, 13 Mar 2006 11:03:15 GMT]]></title><description><![CDATA[<p>Schau dir mal <a href="http://cvs.sourceforge.net/viewcvs.py/loki-lib/loki/include/loki/Functor.h?rev=1.19&amp;view=markup" rel="nofollow">Functor aus Loki</a> an</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1015150</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1015150</guid><dc:creator><![CDATA[LokiFunctor]]></dc:creator><pubDate>Mon, 13 Mar 2006 11:03:15 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Vector von Funktoren on Mon, 13 Mar 2006 11:33:15 GMT]]></title><description><![CDATA[<p>LokiFunctor schrieb:</p>
<blockquote>
<p>Schau dir mal <a href="http://cvs.sourceforge.net/viewcvs.py/loki-lib/loki/include/loki/Functor.h?rev=1.19&amp;view=markup" rel="nofollow">Functor aus Loki</a> an</p>
</blockquote>
<p>Noch besser ist die praxis-erprobte Variante aus der boost-Library. <a href="http://www.boost.org/doc/html/function.html" rel="nofollow">Hier</a> findet mantiz alles was er braucht.</p>
<p>Gruß<br />
Werner</p>
<p>Edit: Doch nicht 'alles'. <a href="http://www.boost.org/libs/bind/bind.html" rel="nofollow">boost.bind</a> braucht man auch noch. Dann bleiben aber keine Wünsche in Sachen Callback mehr offen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1015157</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1015157</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Mon, 13 Mar 2006 11:33:15 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Vector von Funktoren on Mon, 13 Mar 2006 11:49:13 GMT]]></title><description><![CDATA[<p>LokiFunctor schrieb:</p>
<blockquote>
<p>Schau dir mal <a href="http://cvs.sourceforge.net/viewcvs.py/loki-lib/loki/include/loki/Functor.h?rev=1.19&amp;view=markup" rel="nofollow">Functor aus Loki</a> an</p>
</blockquote>
<p>Werner Salomon schrieb:</p>
<blockquote>
<p>LokiFunctor schrieb:</p>
<blockquote>
<p>Schau dir mal <a href="http://cvs.sourceforge.net/viewcvs.py/loki-lib/loki/include/loki/Functor.h?rev=1.19&amp;view=markup" rel="nofollow">Functor aus Loki</a> an</p>
</blockquote>
<p>Noch besser ist die praxis-erprobte Variante aus der boost-Library. <a href="http://www.boost.org/doc/html/function.html" rel="nofollow">Hier</a> findet mantiz alles was er braucht.</p>
<p>Gruß<br />
Werner</p>
</blockquote>
<p>Danke, ich werd's mir auf jeden Fall mal ansehen, allerdings geht es mir ja gerade darum zu lernen und nicht irgendwelche Bibliotheken zu verwenden. <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 hab's jetzt auf die Schnelle so umgesetzt, muss ich aber noch 'in schön' machen:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;map&gt;
#include &lt;vector&gt;

void test() {
	std::cout &lt;&lt; &quot;test()&quot; &lt;&lt; std::endl;
}

class Test {
	public:
		void test() {
			std::cout &lt;&lt; &quot;Test::test()&quot; &lt;&lt; std::endl;
		}
};

class Test2 {
	public:
		void test() {
			std::cout &lt;&lt; &quot;Test2::test()&quot; &lt;&lt; std::endl;
		}
};

class FunctorBase {
	public:
		virtual void operator()() = 0;
		virtual ~FunctorBase() {}
};

template&lt;class C&gt;
class FunctorM : public FunctorBase {
	public:
		FunctorM(C* _o, void (C::* _m)()) : Object(_o), Method(_m) {}

		virtual void operator()() {
			(*this-&gt;Object.*this-&gt;Method)();
		}

	private:
		C* Object;
		void (C::* Method)();
};

class FunctorF : public FunctorBase {
	public:
		FunctorF(void (* _fun)()) : Fun(_fun) {}

		virtual void operator()() {
			(*this-&gt;Fun)();
		}

	private:
		void (* Fun)();
};

class EventHandler {
	public:
		enum EventType {
			onSize,
			onClose,
		};

		void addListener(EventType _e, void (* _f)()) {
			EventTable[_e].push_back(new FunctorF(_f));
		}
		template&lt;class C&gt;
		void addListener(EventType _e, C* _o, void (C::* _m)()) {
			EventTable[_e].push_back(new FunctorM&lt;C&gt;(_o, _m));
		}
		void notifyListener(EventType _e) {
			for (int i = 0; i &lt; EventTable[_e].size(); i++) {
				(*EventTable[_e][i])();
			}
		}
	private:
		typedef std::map&lt;EventType, std::vector&lt;FunctorBase*&gt; &gt; EventTableType;
		EventTableType EventTable;
};

int main() {
	Test  t;
	Test2 t2;

	EventHandler evt;
	evt.addListener(EventHandler::onSize, &amp;test);
	evt.addListener(EventHandler::onSize, &amp;t, &amp;Test::test);
	evt.addListener(EventHandler::onClose, &amp;t2, &amp;Test2::test);

	evt.notifyListener(EventHandler::onSize);
	evt.notifyListener(EventHandler::onClose);

	return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1015185</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1015185</guid><dc:creator><![CDATA[mantiz]]></dc:creator><pubDate>Mon, 13 Mar 2006 11:49:13 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Vector von Funktoren on Mon, 13 Mar 2006 11:54:44 GMT]]></title><description><![CDATA[<p>Ja, so geht's auch <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="😉"
    /> Allerdings solltest du die Namen mit _ besser dem Compiler überlassen (da könnte es Probleme geben).</p>
<p>(und du brauchst noch einen Dtor für deinen EventHandler, der die ganzen per new erzeugten Funktor-Objekte wieder freigibt).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1015193</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1015193</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Mon, 13 Mar 2006 11:54:44 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Vector von Funktoren on Mon, 13 Mar 2006 12:12:54 GMT]]></title><description><![CDATA[<p>CStoll schrieb:</p>
<blockquote>
<p>Ja, so geht's auch <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="😉"
    /> Allerdings solltest du die Namen mit _ besser dem Compiler überlassen (da könnte es Probleme geben).</p>
</blockquote>
<p>Oh, das ist mir neu. Ich finde das so eigentlich ganz nett, um die Parameter besser von anderen Variablen zu unterscheiden. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /> Dann muss ich mir da was anderes einfallen lassen. <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="😉"
    /></p>
<p>CStoll schrieb:</p>
<blockquote>
<p>(und du brauchst noch einen Dtor für deinen EventHandler, der die ganzen per new erzeugten Funktor-Objekte wieder freigibt).</p>
</blockquote>
<p>Ja, der kommt noch, das war bei 'in schön machen' mitinbegriffen. <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>Vielen Dank für die Hilfe. <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/1015214</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1015214</guid><dc:creator><![CDATA[mantiz]]></dc:creator><pubDate>Mon, 13 Mar 2006 12:12:54 GMT</pubDate></item></channel></rss>