<?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[Komplexe Templates führen zu Compilerfehler - warum?]]></title><description><![CDATA[<p>Hallo alle zusammen,</p>
<p>ich versuche derzeit eine Art &quot;Event-Klasse&quot; zu schreiben, die es mir ermöglicht beliebige Funktions-Pointer mit einem Fixen-Parameter in eine Liste zu speichern.</p>
<p>Das heißt symbolisch:<br />
void funktion( void *fixerParameter, int variablerParameter );<br />
funktionsListe-&gt;add( &amp;funktion, meinFixerWert )</p>
<p>Später beim aufruf ist es dann: funktionsListe-&gt;call( 12345 );</p>
<p>Die fixen Parameter benutze ich sogesehen als festen Pointer auf eine Klasseninstanz. Aber das ist was anderes und funktioniert auch.</p>
<p>Soweit so gut, dafür habe ich nun folgende Struktur, die den Funktionspointer und den fixen Wert speichert:</p>
<pre><code class="language-cpp">template&lt;typename T&gt; struct PKSignalContainer
{
    PKSignalContainer&lt;T&gt;() {}
    PKSignalContainer&lt;T&gt;(T m, void *t){ method=m; instance=t; }

    T      method;
    void*  instance;
};
</code></pre>
<p>Der Templatetyp &quot;T&quot; gibt hierbei den Typ des Funktionszeigers an. Außerdem gibt es eine Basis-Klasse für alle Signalklassen:</p>
<pre><code class="language-cpp">template&lt;typename T&gt; struct PKSignalBase {
protected:
    std::vector&lt; PKSignalContainer&lt;T&gt; &gt; events;

public:
    void add( void *meth, void *inst ) {
        events.push_back( PKSignalContainer&lt;T&gt;( meth, inst) );
    }

    // ...
};
</code></pre>
<p>Auch hier gibt &quot;T&quot; den Typen des Funktionszeigers an. Nun zum eigentlichem Signal.</p>
<p>Fall 1: Signale OHNE Parameter</p>
<pre><code class="language-cpp">struct PKSignal : public PKSignalBase&lt;void(*)(void*)&gt; {
    void call( ) {
        std::vector&lt; PKSignalContainer&lt;void(*)(void*)&gt; &gt;::iterator it;
        for( it=events.begin(); it!=events.end(); it++ ) {
            it-&gt;method( it-&gt;instance );
        }
    }
};
</code></pre>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/26a0.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--warning"
      title=":warning:"
      alt="⚠"
    /><br />
Diese Struktur funktioniert problemlos. Jetzt kommt mein eigentliches Problem:</p>
<p>Fall 2: Signal mit einem Parameter</p>
<pre><code class="language-cpp">template&lt;typename T1&gt; struct PKSignal1 : public PKSignalBase&lt;void(*)(void*,T1)&gt; {
public:
	void call( T1 v1 ) {
		// Hier passiert es
		std::vector&lt; PKSignalContainer&lt;void(*)(void*,T1)&gt; &gt;::iterator it;
		for( iterator it=events.begin(); it!=events.end(); it++ ) it-&gt;method( it-&gt;instance, v1 );
	}
};
</code></pre>
<p>Gedanke dahinter war, dass ich flexible Signale definieren kann. Beispiel:<br />
PKSignal1&lt; int &gt; SignalMitIntParameter;<br />
PKSignal1&lt; float &gt; SignalMitFloatParameter;</p>
<p>Diese Struktur führt zu einem Fehler `error: expected `;' before &quot;it&quot;` in der Zeile, in der ich den Iterator definiere.</p>
<p>Seltsamerweise funktioniert das Ganze wiederum problemlos wenn ich in jener Zeile das 'T1' durch 'int' Beispielsweise ersetze. Ich habe es auch schon mit typedefs innerhalb der Klassen probiert - aber alles klappt bislang leider nicht.</p>
<p>Jetzt bräuchte ich doch mal einen Rat. Ich benutze als Compiler g++ version 3.4.2 (mingw-special).</p>
<p>Nochmal zum rauskopieren hier der gesamte Quellcode in meiner jetzigen - unkommentierten - Version.</p>
<pre><code class="language-cpp">#include &lt;vector&gt;

template&lt;typename T&gt; struct PKSignalContainer
{
	PKSignalContainer&lt;T&gt;() {}
	PKSignalContainer&lt;T&gt;(T m, void *t){ method=m; instance=t; }

	T	method;
	void*	instance;
};

template&lt;typename T&gt; struct PKSignalBase
{
protected:
	std::vector&lt; PKSignalContainer&lt;T&gt; &gt; events;

public:
	void add( void *meth, void *inst ) {
		events.push_back( PKSignalContainer&lt;T&gt;( meth, inst ) );
	}
	void clear( ) {
		events.clear( );
	}
}; 

struct PKSignal : public PKSignalBase&lt;void(*)(void*)&gt; {
	void call( ) {
		std::vector&lt; PKSignalContainer&lt;void(*)(void*)&gt; &gt;::iterator it;
		for( it=events.begin(); it!=events.end(); it++ ) it-&gt;method( it-&gt;instance );
	}
};

template&lt;typename T1&gt; struct PKSignal1 : public PKSignalBase&lt;void(*)(void*,T1)&gt; {
public:
	void call( T1 v1 ) {
		// Hier passiert der Fehler, es sei denn ich ersetze T1 durch einen fixen Typ
		std::vector&lt; PKSignalContainer&lt;void(*)(void*,T1)&gt; &gt;::iterator it;
		for( iterator it=events.begin(); it!=events.end(); it++ ) it-&gt;method( it-&gt;instance, v1 );
	}
};
</code></pre>
<p>Über kleine Tipps wäre ich dankbar <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="🙂"
    /> Vielleicht auch eine sauberere Lösung als dieses hier die dann auch funktioniert *g*</p>
<p>Vielen Dank im voraus für jede Hilfe!</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/258565/komplexe-templates-führen-zu-compilerfehler-warum</link><generator>RSS for Node</generator><lastBuildDate>Wed, 09 Sep 2026 06:35:42 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/258565.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 12 Jan 2010 10:10:38 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Komplexe Templates führen zu Compilerfehler - warum? on Tue, 12 Jan 2010 10:10:38 GMT]]></title><description><![CDATA[<p>Hallo alle zusammen,</p>
<p>ich versuche derzeit eine Art &quot;Event-Klasse&quot; zu schreiben, die es mir ermöglicht beliebige Funktions-Pointer mit einem Fixen-Parameter in eine Liste zu speichern.</p>
<p>Das heißt symbolisch:<br />
void funktion( void *fixerParameter, int variablerParameter );<br />
funktionsListe-&gt;add( &amp;funktion, meinFixerWert )</p>
<p>Später beim aufruf ist es dann: funktionsListe-&gt;call( 12345 );</p>
<p>Die fixen Parameter benutze ich sogesehen als festen Pointer auf eine Klasseninstanz. Aber das ist was anderes und funktioniert auch.</p>
<p>Soweit so gut, dafür habe ich nun folgende Struktur, die den Funktionspointer und den fixen Wert speichert:</p>
<pre><code class="language-cpp">template&lt;typename T&gt; struct PKSignalContainer
{
    PKSignalContainer&lt;T&gt;() {}
    PKSignalContainer&lt;T&gt;(T m, void *t){ method=m; instance=t; }

    T      method;
    void*  instance;
};
</code></pre>
<p>Der Templatetyp &quot;T&quot; gibt hierbei den Typ des Funktionszeigers an. Außerdem gibt es eine Basis-Klasse für alle Signalklassen:</p>
<pre><code class="language-cpp">template&lt;typename T&gt; struct PKSignalBase {
protected:
    std::vector&lt; PKSignalContainer&lt;T&gt; &gt; events;

public:
    void add( void *meth, void *inst ) {
        events.push_back( PKSignalContainer&lt;T&gt;( meth, inst) );
    }

    // ...
};
</code></pre>
<p>Auch hier gibt &quot;T&quot; den Typen des Funktionszeigers an. Nun zum eigentlichem Signal.</p>
<p>Fall 1: Signale OHNE Parameter</p>
<pre><code class="language-cpp">struct PKSignal : public PKSignalBase&lt;void(*)(void*)&gt; {
    void call( ) {
        std::vector&lt; PKSignalContainer&lt;void(*)(void*)&gt; &gt;::iterator it;
        for( it=events.begin(); it!=events.end(); it++ ) {
            it-&gt;method( it-&gt;instance );
        }
    }
};
</code></pre>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/26a0.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--warning"
      title=":warning:"
      alt="⚠"
    /><br />
Diese Struktur funktioniert problemlos. Jetzt kommt mein eigentliches Problem:</p>
<p>Fall 2: Signal mit einem Parameter</p>
<pre><code class="language-cpp">template&lt;typename T1&gt; struct PKSignal1 : public PKSignalBase&lt;void(*)(void*,T1)&gt; {
public:
	void call( T1 v1 ) {
		// Hier passiert es
		std::vector&lt; PKSignalContainer&lt;void(*)(void*,T1)&gt; &gt;::iterator it;
		for( iterator it=events.begin(); it!=events.end(); it++ ) it-&gt;method( it-&gt;instance, v1 );
	}
};
</code></pre>
<p>Gedanke dahinter war, dass ich flexible Signale definieren kann. Beispiel:<br />
PKSignal1&lt; int &gt; SignalMitIntParameter;<br />
PKSignal1&lt; float &gt; SignalMitFloatParameter;</p>
<p>Diese Struktur führt zu einem Fehler `error: expected `;' before &quot;it&quot;` in der Zeile, in der ich den Iterator definiere.</p>
<p>Seltsamerweise funktioniert das Ganze wiederum problemlos wenn ich in jener Zeile das 'T1' durch 'int' Beispielsweise ersetze. Ich habe es auch schon mit typedefs innerhalb der Klassen probiert - aber alles klappt bislang leider nicht.</p>
<p>Jetzt bräuchte ich doch mal einen Rat. Ich benutze als Compiler g++ version 3.4.2 (mingw-special).</p>
<p>Nochmal zum rauskopieren hier der gesamte Quellcode in meiner jetzigen - unkommentierten - Version.</p>
<pre><code class="language-cpp">#include &lt;vector&gt;

template&lt;typename T&gt; struct PKSignalContainer
{
	PKSignalContainer&lt;T&gt;() {}
	PKSignalContainer&lt;T&gt;(T m, void *t){ method=m; instance=t; }

	T	method;
	void*	instance;
};

template&lt;typename T&gt; struct PKSignalBase
{
protected:
	std::vector&lt; PKSignalContainer&lt;T&gt; &gt; events;

public:
	void add( void *meth, void *inst ) {
		events.push_back( PKSignalContainer&lt;T&gt;( meth, inst ) );
	}
	void clear( ) {
		events.clear( );
	}
}; 

struct PKSignal : public PKSignalBase&lt;void(*)(void*)&gt; {
	void call( ) {
		std::vector&lt; PKSignalContainer&lt;void(*)(void*)&gt; &gt;::iterator it;
		for( it=events.begin(); it!=events.end(); it++ ) it-&gt;method( it-&gt;instance );
	}
};

template&lt;typename T1&gt; struct PKSignal1 : public PKSignalBase&lt;void(*)(void*,T1)&gt; {
public:
	void call( T1 v1 ) {
		// Hier passiert der Fehler, es sei denn ich ersetze T1 durch einen fixen Typ
		std::vector&lt; PKSignalContainer&lt;void(*)(void*,T1)&gt; &gt;::iterator it;
		for( iterator it=events.begin(); it!=events.end(); it++ ) it-&gt;method( it-&gt;instance, v1 );
	}
};
</code></pre>
<p>Über kleine Tipps wäre ich dankbar <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="🙂"
    /> Vielleicht auch eine sauberere Lösung als dieses hier die dann auch funktioniert *g*</p>
<p>Vielen Dank im voraus für jede Hilfe!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1837382</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1837382</guid><dc:creator><![CDATA[ProfEich]]></dc:creator><pubDate>Tue, 12 Jan 2010 10:10:38 GMT</pubDate></item><item><title><![CDATA[Reply to Komplexe Templates führen zu Compilerfehler - warum? on Tue, 12 Jan 2010 10:18:39 GMT]]></title><description><![CDATA[<p>Da du das vector-template nicht vollständig instantiierst, ist vector&lt;.......&gt;::iterator ein abhängiger Name und muss als typ gekennzeichnet werden -&gt; typename</p>
<pre><code class="language-cpp">template&lt;typename T1&gt; struct PKSignal1 : public PKSignalBase&lt;void(*)(void*,T1)&gt; {
public:
    void call( T1 v1 ) {
        // Hier typename einbauen!
        typename std::vector&lt; PKSignalContainer&lt;void(*)(void*,T1)&gt; &gt;::iterator it;
        for( /*das iterator hier war zu viel*/ it=events.begin(); it!=events.end(); it++ ) it-&gt;method( it-&gt;instance, v1 );
    }
};
</code></pre>
<p>Zur Vereinfachung würde ich sowas machen:</p>
<pre><code class="language-cpp">template&lt;typename T&gt; struct PKSignalBase {
protected:
    std::vector&lt; PKSignalContainer&lt;T&gt; &gt; events;
    typedef typename std::vector&lt; PKSignalContainer&lt;T&gt; &gt;::iterator eventiter;

    // ...
};
</code></pre>
<p>und dann den eventiter-typedef in den abgeleiteten Klassen nutzen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1837391</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1837391</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Tue, 12 Jan 2010 10:18:39 GMT</pubDate></item></channel></rss>