<?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[Template Problem]]></title><description><![CDATA[<p>Hallo,<br />
ich arbeite zum ersten mal mit Templates und wollte zum Probieren<br />
mal eine einfache verkettete Liste programmieren. Jetzt meldet<br />
mir der Compiler einen Fehler und ich kann ihn einfach nicht finden.<br />
Ich schätze, das Problem hängt mit der inneren Klasse zusammen.<br />
Kann mir jemand helfen?!</p>
<p>Gruß Ronny</p>
<p>Hier der Quellcode:</p>
<pre><code>#include &lt;stdio.h&gt;

template &lt;class T&gt;
class Liste
{
	public:

	Liste();
	void add( T &amp;value );

	private:
	class Listenknoten {
		public:
		Listenknoten( T *value, Listenknoten *ne );

		T* val;
		Listenknoten* pnext;
	};

	Listenknoten *first;

};

template &lt;class T&gt;
Liste&lt;T&gt;::Liste()
{

}

template &lt;class T&gt;
void Liste&lt;T&gt;::add( T &amp;value )
{
	// Zeile mal auskommentieren
	new Listenknoten( &amp;value, NULL );

}

template &lt;class T&gt;
Liste&lt;T&gt;::Listenknoten::Listenknoten( T *value, Listenknoten *ne )
{
	val = value;
	pnext = ne;
}

int main(){
	Liste&lt;int&gt; li;

	int a=3;
	li.add( a );

 return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/153504/template-problem</link><generator>RSS for Node</generator><lastBuildDate>Mon, 07 Sep 2026 14:06:47 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/153504.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 17 Jul 2006 21:53:04 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Template Problem on Mon, 17 Jul 2006 21:53:04 GMT]]></title><description><![CDATA[<p>Hallo,<br />
ich arbeite zum ersten mal mit Templates und wollte zum Probieren<br />
mal eine einfache verkettete Liste programmieren. Jetzt meldet<br />
mir der Compiler einen Fehler und ich kann ihn einfach nicht finden.<br />
Ich schätze, das Problem hängt mit der inneren Klasse zusammen.<br />
Kann mir jemand helfen?!</p>
<p>Gruß Ronny</p>
<p>Hier der Quellcode:</p>
<pre><code>#include &lt;stdio.h&gt;

template &lt;class T&gt;
class Liste
{
	public:

	Liste();
	void add( T &amp;value );

	private:
	class Listenknoten {
		public:
		Listenknoten( T *value, Listenknoten *ne );

		T* val;
		Listenknoten* pnext;
	};

	Listenknoten *first;

};

template &lt;class T&gt;
Liste&lt;T&gt;::Liste()
{

}

template &lt;class T&gt;
void Liste&lt;T&gt;::add( T &amp;value )
{
	// Zeile mal auskommentieren
	new Listenknoten( &amp;value, NULL );

}

template &lt;class T&gt;
Liste&lt;T&gt;::Listenknoten::Listenknoten( T *value, Listenknoten *ne )
{
	val = value;
	pnext = ne;
}

int main(){
	Liste&lt;int&gt; li;

	int a=3;
	li.add( a );

 return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1099465</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1099465</guid><dc:creator><![CDATA[Gast_Ronny]]></dc:creator><pubDate>Mon, 17 Jul 2006 21:53:04 GMT</pubDate></item><item><title><![CDATA[Reply to Template Problem on Mon, 17 Jul 2006 21:54:55 GMT]]></title><description><![CDATA[<p>Dazu wäre es nicht schlecht, den Compilerfehler mal zu sehen ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1099466</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1099466</guid><dc:creator><![CDATA[megaweber]]></dc:creator><pubDate>Mon, 17 Jul 2006 21:54:55 GMT</pubDate></item><item><title><![CDATA[Reply to Template Problem on Mon, 17 Jul 2006 21:55:56 GMT]]></title><description><![CDATA[<p>Linker-Vorgang läuft...<br />
Template.obj : error LNK2001: Nichtaufgeloestes externes Symbol &quot;public: __thiscall Liste&lt;int&gt;::Listenknoten::Listenknoten(int *,class Liste&lt;int&gt;::Listenknoten *)&quot; (??0Listenknoten@?$Liste@H@@QAE@PAHPAV01@@Z)<br />
Debug/Templates.exe : fatal error LNK1120: 1 unaufgeloeste externe Verweise<br />
Fehler beim Ausführen von link.exe.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1099468</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1099468</guid><dc:creator><![CDATA[Gast_Ronny]]></dc:creator><pubDate>Mon, 17 Jul 2006 21:55:56 GMT</pubDate></item><item><title><![CDATA[Reply to Template Problem on Tue, 18 Jul 2006 02:03:38 GMT]]></title><description><![CDATA[<p>Der Fehler hat was mit der Schachtelung von templates zu tun. So funktioniert's:</p>
<pre><code class="language-cpp">#include &lt;new&gt;
#include &lt;iostream&gt;

using namespace std;

template&lt; typename T &gt;
class list_t {

    private:

        template&lt; typename T &gt;
        class node_t {

            public:

                template&lt; typename T &gt;
                node_t( T &amp;value ) : m_value( value ), m_next( 0 ) { }

                void g( );

                T m_value;
                node_t&lt; T &gt; *m_next;
        };

    public:

        list_t( );
        bool empty( );
        size_t size( );
        T begin( );
        T end( );
        T at( size_t index );
        void push_front( const T &amp;value ) throw( ... );
        void push_back( const T &amp;value ) throw( ... );	
        void pop_front( );
        void pop_back( );

    private:

        node_t&lt; T &gt; *m_first;
        node_t&lt; T &gt; *m_end;
        size_t m_size;
};

// das würde funktionieren, da die funktion selbst keinen
// Template-Parameter benötigt.
template&lt; typename T &gt;
void list_t&lt; T &gt;::node_t&lt; T &gt;::g( )
{
}

template&lt; typename T &gt;
list_t&lt; T &gt;::list_t( ) : m_first( 0 ), m_end( 0 ), m_size( 0 )
{
}

template&lt; typename T &gt;
bool list_t&lt; T &gt;::empty( )
{
    return m_first == 0;
}

template&lt; typename T &gt;
size_t list_t&lt; T &gt;::size( )
{
    return m_size;
}

template&lt; typename T &gt;
T list_t&lt; T &gt;::begin( )
{
    return m_first-&gt;m_value;
}

template&lt; typename T &gt;
T list_t&lt; T &gt;::end( )
{
    return m_end-&gt;m_value;
}

template&lt; typename T &gt;
void list_t&lt; T &gt;::push_front( const T &amp;value ) throw( ... )
{
    node_t&lt; T &gt; *tmp;

    try {
        tmp = new node_t&lt; T &gt;( value );
    } catch( std::bad_alloc &amp;ba ) {
        throw &amp;ba;
    }

    ++m_size;

    if( !m_first ) {
        m_first = tmp;
        return;
    }

    tmp-&gt;m_next = m_first;
    m_first = tmp;
}

template&lt; typename T &gt;
void list_t&lt; T &gt;::push_back( const T &amp;value ) throw( ... )
{
    node_t&lt; T &gt; *tmp;

    try {
        tmp = new node_t&lt; T &gt;( value );
    } catch( std::bad_alloc &amp;ba ) {
        throw( ba );
    }

    ++m_size;

    if( !m_first ) {
        m_end = m_first = tmp;
        return;
    }

    node_t&lt; T &gt; *cur = m_first;

    while( cur-&gt;m_next )
        cur = cur-&gt;m_next;

    m_end = cur-&gt;m_next = tmp;
}

template&lt; typename T &gt;
void list_t&lt; T &gt;::pop_front( )
{
    if( m_size == 1 ) {

        delete m_first;
        m_first = 0;
        m_size = 0;

    } else if( m_size &gt; 1 ) {

        node_t&lt; T &gt; *tmp = m_first-&gt;m_next;
        delete m_first;
        m_first = tmp;
        --m_size;
    }
}

template&lt; typename T &gt;
void list_t&lt; T &gt;::pop_back( )
{
    if( m_size == 1 ) {

        delete m_first;
        m_end = 0;
        --m_size;

    } else if( m_size &gt; 1 ) {

        node_t&lt; T &gt; *cur = m_first;	

        while( cur-&gt;m_next-&gt;m_next )
            cur = cur-&gt;m_next;

        delete cur-&gt;m_next;
        m_end = cur;
    }
}

template&lt; typename T &gt;
T list_t&lt; T &gt;::at( size_t index )
{
    if( index &lt; m_size ) {

        if( index == 0 )
            return m_first-&gt;m_value;

        if( index == ( m_size - 1 ) ) {
            return m_end-&gt;m_value;

        node_t&lt; T &gt; *cur = m_first-&gt;m_next;

        for( size_t i = 1; i &lt; index; ++i )
            cur = cur-&gt;m_next;

        return cur-&gt;m_value;
    }
    return 0;
}

int main( )
{
    list_t&lt; int &gt; list;

    list.push_back( 1 );
    list.push_back( 2 );
    list.push_back( 3 );

    cout &lt;&lt; list.begin( ) &lt;&lt; endl;
    cout &lt;&lt; list.end( ) &lt;&lt; endl;

    list.push_front( 0 );
    cout &lt;&lt; list.begin( ) &lt;&lt; endl;

    list.pop_front( );
    cout &lt;&lt; list.begin( ) &lt;&lt; endl;

    cout &lt;&lt; list.at( 0 ) &lt;&lt; endl;
    cout &lt;&lt; list.at( 1 ) &lt;&lt; endl;
    cout &lt;&lt; list.at( 2 ) &lt;&lt; endl;

    list.push_back( 3 );
    cout &lt;&lt; list.at( 3 ) &lt;&lt; endl;
}
</code></pre>
<p>Greetz, Swordfish</p>
<p>PS: Viel Spaß bei'm erweitern... <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>
]]></description><link>https://www.c-plusplus.net/forum/post/1099498</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1099498</guid><dc:creator><![CDATA[Swordfish]]></dc:creator><pubDate>Tue, 18 Jul 2006 02:03:38 GMT</pubDate></item><item><title><![CDATA[Reply to Template Problem on Tue, 18 Jul 2006 08:58:02 GMT]]></title><description><![CDATA[<p>Vielen Dank für die Antwort. Habe mein Programm ein wenig umgebaut.<br />
Scheinbar funktioniert es nur wenn der Konstruktor der inneren Klasse<br />
gleich in der Deklaration initialisiert wird.<br />
Also ich hätte sonst in der Klasse Listnode den Konstruktor deklariert,<br />
einfach nur mit</p>
<pre><code class="language-cpp">Listnode( T *val );
</code></pre>
<p>und dann die Implementierung separat vorgenommen.</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
Liste&lt;T&gt;::Listenknoten&lt;T&gt;::Listenknoten( T *value ):
	val( value ), pnext( NULL );
{
}
</code></pre>
<p>So ganz verstehe ich aber nicht, wieso meine Variante nicht funktioniert.<br />
Kann mir das jemand erklären?</p>
<pre><code class="language-cpp">#include &lt;stdio.h&gt;

template &lt;typename T&gt;
class Liste {

private:

	//////////////
	template &lt;typename T&gt;
	class Listenknoten {

	public:

		template &lt;typename T&gt;
		Listenknoten( T *value ) : val(value),pnext(NULL)
		{
		}

		T *val;
		Listenknoten&lt;T&gt; *pnext ;
	};
        //////////////

	Listenknoten&lt;T&gt; *first;

public:

	Liste();
	void add( T &amp;value );
};

template &lt;typename T&gt;
Liste&lt;T&gt;::Liste() : first( NULL )
{
}

template &lt;typename T&gt;
void Liste&lt;T&gt;::add( T &amp;value )
{
	// hier Fehler
	new Listenknoten&lt;T&gt;( &amp;value );
}

int main(){
	Liste&lt;int&gt; li;

	int a=3;
	li.add( a );

 return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1099611</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1099611</guid><dc:creator><![CDATA[Gast_Ronny]]></dc:creator><pubDate>Tue, 18 Jul 2006 08:58:02 GMT</pubDate></item><item><title><![CDATA[Reply to Template Problem on Tue, 18 Jul 2006 10:46:05 GMT]]></title><description><![CDATA[<p>Versuchs mal damit:</p>
<pre><code class="language-cpp">template &lt;typename T&gt; 
void Liste&lt;T&gt;::add( T &amp;value ) 
{   
new Liste&lt;T&gt;::Listenknoten&lt;T&gt;( &amp;value ); 
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1099663</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1099663</guid><dc:creator><![CDATA[Mathias]]></dc:creator><pubDate>Tue, 18 Jul 2006 10:46:05 GMT</pubDate></item><item><title><![CDATA[Reply to Template Problem on Tue, 18 Jul 2006 10:26:40 GMT]]></title><description><![CDATA[<p>Ansonsten stellt sich mir die Frage weshalb du eine Klasse innerhalb einer anderen definierst. Die innere Klasse wird nach Außen gegeben und dann hat man im Code irgendwann solche schönen Bezeichner-Orgien:</p>
<p>namespace::class::class:: ... ::function</p>
<p>...oder man bemüht wieder typedefs um die Sache dann wieder einfacher zu machen... was den Code natürlich viel lesbarer macht. *hust*</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1099671</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1099671</guid><dc:creator><![CDATA[Mathias]]></dc:creator><pubDate>Tue, 18 Jul 2006 10:26:40 GMT</pubDate></item><item><title><![CDATA[Reply to Template Problem on Tue, 18 Jul 2006 12:32:15 GMT]]></title><description><![CDATA[<p>Gute Idee aber leider funktioniert das auch nicht.<br />
Aber recht hast Du eigentlich, man könnte das ohne innere<br />
Klasse machen. Wahrscheinlich würde es dann gehen.</p>
<p>Ok, vielen Dank für die Antworten!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1099771</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1099771</guid><dc:creator><![CDATA[Gast_Ronny]]></dc:creator><pubDate>Tue, 18 Jul 2006 12:32:15 GMT</pubDate></item><item><title><![CDATA[Reply to Template Problem on Tue, 18 Jul 2006 21:43:16 GMT]]></title><description><![CDATA[<p>Mathias schrieb:</p>
<blockquote>
<p>Ansonsten stellt sich mir die Frage weshalb du eine Klasse innerhalb einer anderen definierst.</p>
</blockquote>
<p>Bei einer Liste bietet es sich schon an, den Node als nested Klasse zu implementieren. Das ist nichts Ungewöhnliches.</p>
<p>Mathias schrieb:</p>
<blockquote>
<p>Die innere Klasse wird nach Außen gegeben</p>
</blockquote>
<p>Wieso nach Aussen? Der Client sollte den Node auf jeden Fall nie zu Gesicht bekommen. Nur innerhalb der Liste ist er von Bedeutung.</p>
<pre><code class="language-cpp">#include &lt;stdio.h&gt;

template &lt;typename T&gt;
class Liste {

private:

	//////////////
	template &lt;typename T&gt;
	class Listenknoten {
</code></pre>
<p>IIRC dürfte das kein gültiger Code sein. Mal abgesehen davon, dass es &lt;cstdio&gt; sein muss, wird hier zweimal der Template Parameter T definiert. Stichwort: Shadow Template Parameter. Zudem muss Listenknoten kein Template sein, immerhin kennt die Klasse den Elementtyp.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1100078</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1100078</guid><dc:creator><![CDATA[groovemaster]]></dc:creator><pubDate>Tue, 18 Jul 2006 21:43:16 GMT</pubDate></item><item><title><![CDATA[Reply to Template Problem on Wed, 19 Jul 2006 07:57:43 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/2813">@groovemaster</a><br />
Ich hab ja auch nicht gesagt, dass es etwas ungewöhnliches ist oder dass man es nicht tun darf.<br />
Ich meinte nur, dass sich daraus ziemlich lange Bezeichner ergeben.</p>
<p>Ansonsten hast du recht die Knoten in dem Beispiel ist die Knotenklasse private, so dass es sich an der Stelle hier nicht auf die Schnittstelle der Liste auswirkt.</p>
<blockquote>
<p>Wieso nach Aussen? Der Client sollte den Node auf jeden Fall nie zu Gesicht bekommen. Nur innerhalb der Liste ist er von Bedeutung.</p>
</blockquote>
<p>Wir reden von zwei unterschiedlichen Dingen. Das eine ist die Schnittstelle der Liste und das andere ist der Zugriff auf die Node-Klasse. Was spricht dagegen die Node-Klasse noch an anderer Stelle zu nutzen, auch wenn ich nicht möchte, dass Node-Objekte über die Schnittstelle der Liste übergeben werden?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1100178</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1100178</guid><dc:creator><![CDATA[Mathias]]></dc:creator><pubDate>Wed, 19 Jul 2006 07:57:43 GMT</pubDate></item><item><title><![CDATA[Reply to Template Problem on Wed, 19 Jul 2006 10:00:24 GMT]]></title><description><![CDATA[<p>Mathias schrieb:</p>
<blockquote>
<p>Wir reden von zwei unterschiedlichen Dingen. Das eine ist die Schnittstelle der Liste und das andere ist der Zugriff auf die Node-Klasse.</p>
</blockquote>
<p>Ich habe aber nur über die Schnittstelle gesprochen. Der Zugriff ist doch praktisch gleich, lediglich mit dem Unterschied, dass der Node entweder einen Scope höher oder niedriger zu finden ist. Das ist aber nicht deine Aufgabe, sondern die des Compilers. Ansonsten gibt es lediglich Unterschiede im Detail.</p>
<p>Mathias schrieb:</p>
<blockquote>
<p>Was spricht dagegen die Node-Klasse noch an anderer Stelle zu nutzen, auch wenn ich nicht möchte, dass Node-Objekte über die Schnittstelle der Liste übergeben werden?</p>
</blockquote>
<p>Nichts. Das kannst du letztendlich machen, wie du lustig bist. Nur sind solche Node Klassen nicht gerade prädestiniert für universellen Einsatz. ZB sieht man die Unterschiede schon am Beispiel einer Liste. Single Linked oder Double Linked? Damit ändert sich schon die Implementation. Klar, du kannst alles umgehen, zB mit Vererbung. Fragt sich nur, ob der Kosten-Nutzen Faktor vertretbar ist. Wie auch immer, alles was ich gesagt habe, war, dass hier eine nested Klasse gängige Praxis ist. Nicht mehr und nicht weniger.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1100266</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1100266</guid><dc:creator><![CDATA[groovemaster]]></dc:creator><pubDate>Wed, 19 Jul 2006 10:00:24 GMT</pubDate></item></channel></rss>